Android 實現拖放控件

相似微信朋友圈刪除圖片效果,示例以下:java

拖放控件1.png

拖放控件2.png

使用 Android 拖放框架 ,能夠讓用戶使用圖形化拖放手勢移動數據。android

監聽拖放過程

實現 View.OnDragListener 的拖動事件監聽器或其 onDragEvent(DragEvent) 回調方法來接收拖動事件。微信

DragEvent 操做類型markdown

getAction() 值 含義
ACTION_DRAG_STARTED 當應用調用 startDrag() 並獲取拖動陰影后,視圖對象的拖動事件監聽器會當即收到此事件操做類型。
ACTION_DRAG_ENTERED 當拖動陰影剛進入視圖的邊界框時,視圖對象的拖動事件監聽器會收到此事件操做類型。這是監聽器在拖動陰影進入邊界框時收到的第一個事件操做類型。若是監聽器想繼續接收此操做的拖動事件,必須向系統返回布爾值 true
ACTION_DRAG_LOCATION 當收到 ACTION_DRAG_ENTERED 事件且拖動陰影仍在視圖的邊界框內時,該視圖對象的拖動事件監聽器會收到此事件操做類型。
ACTION_DRAG_EXITED 當收到 ACTION_DRAG_ENTERED 和至少一個 ACTION_DRAG_LOCATION 事件,而且用戶已將拖動陰影移至視圖的邊界框之外時,該視圖對象的拖動事件監聽器會收到此事件操做類型。
ACTION_DROP 當用戶將拖動陰影釋放到視圖對象上時,該視圖對象的拖動事件監聽器會收到此事件操做類型。僅當視圖對象的監聽器在響應 ACTION_DRAG_STARTED 拖動事件時返回布爾值 true 時,系統纔會將該操做類型發送至該監聽器。若是用戶將拖動陰影釋放到未註冊監聽器的視圖上或不屬於當前佈局的任何視圖上,系統都不會發送此操做類型。若是成功處理了放下操做,監聽器應返回布爾值 true。不然,它應返回 false
ACTION_DRAG_ENDED 當系統結束拖動操做時,視圖對象的拖動事件監聽器會收到此事件操做類型。此操做類型不必定在 ACTION_DROP 事件以後。若是系統已發送 ACTION_DROP,收到 ACTION_DRAG_ENDED 操做類型並不表示放下操做成功。監聽器必須調用 getResult() 才能得到響應 ACTION_DROP 時所返回的值。若是未發送 ACTION_DROP 事件,getResult() 將返回 false

示例代碼以下:框架

private void initDragListener() {

    llDelete.setOnDragListener((v, event) -> {
      final int action = event.getAction();

      switch (action) {
        //開始拖動
        case DragEvent.ACTION_DRAG_STARTED:

          //離開底部刪除按鈕
        case DragEvent.ACTION_DRAG_EXITED:
          //重置底部刪除按鈕文字和顏色
          tvDelete.setText(getString(R.string.delete));
          llDelete.setBackground(
              ResourcesCompat.getDrawable(getResources(), R.color.delete_msg_color, null));

          return true;

        //拖動到底部刪除按鈕中
        case DragEvent.ACTION_DRAG_ENTERED:
		  //改變底部刪除按鈕文字和顏色 
          tvDelete.setText(getString(R.string.delete_hint));
          llDelete
              .setBackground(ResourcesCompat.getDrawable(getResources(), R.color.delete_hint_color, null));
          return true;

        //刪除圖片
        case DragEvent.ACTION_DROP:
          deleteImage();
          return true;

        //拖放結束
        case DragEvent.ACTION_DRAG_ENDED:
          //隱藏底部刪除按鈕 
          showBottomDelete(false);
          tvDelete.setText(getString(R.string.delete));
          llDelete.setBackground(
              ResourcesCompat.getDrawable(getResources(), R.color.delete_msg_color, null));
          return true;

        default:
          break;
      }

      return false;
    });

  }

  private void deleteImage() {
    imageView.setVisibility(View.GONE);
  }
複製代碼

開始拖動

根據須要,能夠爲要移動的數據建立 ClipDataClipData.Item。這個數據經過 DragEvent.getClipData() 方法獲取。ide

若是不須要也能夠直接置空。oop

//長按圖片觸發刪除事件 
imageView.setOnLongClickListener(new OnLongClickListener() {
      @Override
      public boolean onLongClick(View view) {

        showBottomDelete(true);
        //建立須要移動的數據,若是沒有能夠直接置空 
        ClipData.Item item = new Item("");
        ClipData data = new ClipData("", new String[]{ClipDescription.MIMETYPE_TEXT_PLAIN},
            item);
          
        //設置拖動的陰影,能夠自定義,這邊直接使用ImageView 
        View.DragShadowBuilder myShadow = new DragShadowBuilder(view);
        
        //開始拖動 
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
          view.startDragAndDrop(data, myShadow, null, 0);
        } else {
          view.startDrag(data, myShadow, null, 0);
        }

        return false;
      }
    });
複製代碼
相關文章
相關標籤/搜索