Android _Drag 學習筆記

View 可以實現拖拽效果(Drag),根據參考API 文檔,實現也簡單。

(Api 文檔: https://tool.oschina.net/uploads/apidocs/android/guide/topics/ui/drag-drop.html)

以下簡單實現了拖拽效果,在拖拽的過程中,根據拖拽事件 更新ImageView 的背景顏色,方便理解拖拽事件的處理。

但是  ACTION_DROP 沒有執行,需要檢查一下原因。

此外,下一步進行研究 拖拽到指定目標View區域, 考慮能拖拽的範圍等等

package com.example.dragtest;

import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;

import android.content.ClipData;
import android.content.ClipDescription;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.DragEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    // Create a string for the ImageView label
    private static final String IMAGEVIEW_TAG = "icon bitmap";
    private Context mContext;

    // Creates a new ImageView
    ImageView mImageView;
    Bitmap mIconBitmap;
    private View.OnDragListener mDragListener;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mContext = this;
        ConstraintLayout layout = findViewById(R.id.main_layout);

        // 動態添加 ImageView, 設置Tag, 拖拽時可以判斷時哪個view
        mImageView = new ImageView(this);
        mIconBitmap = Bitmap.createBitmap(200, 200, Bitmap.Config.ARGB_8888);
        mImageView.setImageBitmap(mIconBitmap);
        mImageView.setTag(IMAGEVIEW_TAG);
        mImageView.setBackgroundColor(getResources().getColor(R.color.colorAccent));

        // 使用ConstraintLayout 方式動態添加ImageView 到佈局中,與Drag 無關,可以直接使用圖片資源代替
        int imageViewId = mImageView.generateViewId();
        ConstraintSet constraintSet = new ConstraintSet();
        constraintSet.connect(imageViewId, ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START);
        constraintSet.connect(imageViewId, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP);
        constraintSet.applyTo(layout);
        layout.addView(mImageView);

        //1. 簡單實現拖拽效果
        mImageView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                //API 文檔使用 ClipData.MIMETYPE_TEXT_PLAIN, 但是無法使用。(MIMETYPES_TEXT_PLAIN)
                String[] textPlain = new String[]{"text/plain"};
                //1.1 ClipData 跟剪貼板有關??
                ClipData.Item item = new ClipData.Item((CharSequence) v.getTag());
                ClipData dragData = new ClipData((CharSequence) v.getTag(), textPlain, item);

                //1.2 拖拽動畫效果有默認實現  DragShadowBuilder
                //開始執行拖拽
                v.startDrag(dragData, new View.DragShadowBuilder(v), null, 0);

                return true;
            }
        });


        //2. 自定義拖拽監聽器,響應各種拖拽事件 (start/enter/location/drop/end)
        mDragListener = new MyDragEventListener();
        mImageView.setOnDragListener(mDragListener);
    }


    protected class MyDragEventListener implements View.OnDragListener {
        @Override
        public boolean onDrag(View v, DragEvent event) {
            final int action = event.getAction();

            switch (action) {
                case DragEvent.ACTION_DRAG_STARTED:
                    if (event.getClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
                        v.setBackgroundColor(Color.BLUE); // 設置圖片背景顏色
                        v.invalidate();
                        // 返回true才能收到後面的時間,否則只能收到end
                        return (true);
                    } else {
                        return (false);
                    }
                    //break;
                case DragEvent.ACTION_DRAG_ENTERED:
                    v.setBackgroundColor(Color.RED); // 設置圖片背景顏色
                    v.invalidate();
                    return true;
                //break;
                case DragEvent.ACTION_DRAG_LOCATION:
                    return true;

                case DragEvent.ACTION_DRAG_EXITED:
                    v.setBackgroundColor(Color.BLACK); // 設置圖片背景顏色
                    v.invalidate();
                    return true;

                //並沒有執行,需要檢查
                case DragEvent.ACTION_DROP:
                    ClipData.Item item = event.getClipData().getItemAt(0);
                    CharSequence dragData = item.getText();
                    Toast.makeText(mContext, "Dragged data is " + dragData, Toast.LENGTH_LONG).show();
                    v.setBackgroundColor(mContext.getResources().getColor(R.color.colorAccent));
                    v.invalidate();
                    return true;

                case DragEvent.ACTION_DRAG_ENDED:
                    v.setBackgroundColor(Color.YELLOW); // 設置圖片背景顏色
                    v.invalidate();
                    if (event.getResult()) {
                        Toast.makeText(mContext, "The drop was handled.", Toast.LENGTH_LONG).show();
                    } else {
                        Toast.makeText(mContext, "The drop didn't work.", Toast.LENGTH_LONG).show();
                    }
                    return true;

                default:
                    Log.e("DragDrop Example", "Unknown action type received by OnDragListener.");
                    break;
            }

            return false;
        }
    }
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章