1. 程式人生 > >Android中Drag and Drop拖拽功能的使用1-----基本實現

Android中Drag and Drop拖拽功能的使用1-----基本實現

Android中的拖拽功能是有自帶的api的;(很多時候會誤以為要自定義控制元件,所以我放到了,自定義目錄下)
參考文件:
http://www.android-doc.com/guide/topics/ui/drag-drop.html
我寫了一個例子分析:
效果圖:
在這裡插入圖片描述
思路:
1主要用到了View的startDrag(startDragAndDrop API24+) 方法
2拖拽的監聽OnDragListener方法
具體實現:
第一步:通過一個長按事件啟動拖拽:

imageView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                Intent intent = new Intent();
                ClipData clipData = ClipData.newIntent("label", intent);

                View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(v);
                v.startDrag(null, shadowBuilder, imageView, 0);
                //震動反饋
                v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
                return true;
            }
        });

第二步:OnDragListener監聽拖拽

linearLayout.setOnDragListener(new View.OnDragListener() {
            @Override
            public boolean onDrag(View v, DragEvent event) {
                //v 永遠是設定該監聽的view,這裡即fl_blue
                String simpleName = v.getClass().getSimpleName();
//                Log.w(BLUE, "view name:" + simpleName);

                //獲取事件
                int action = event.getAction();
                switch (action) {
                    case DragEvent.ACTION_DRAG_STARTED:
                        Log.i("111", "開始拖拽");
                        imageView.setVisibility(View.INVISIBLE);
                        break;
                    case DragEvent.ACTION_DRAG_ENDED:
                        Log.i("111", "結束拖拽");
                        imageView.setVisibility(View.VISIBLE);
                        break;
                    case DragEvent.ACTION_DRAG_ENTERED:
                        Log.i("111", "拖拽的view進入監聽的view時");
                        break;
                    case DragEvent.ACTION_DRAG_EXITED:
                        Log.i("111", "拖拽的view離開監聽的view時");
                        break;
                    case DragEvent.ACTION_DRAG_LOCATION:
                        float x = event.getX();
                        float y = event.getY();
                        long l = SystemClock.currentThreadTimeMillis();
                        Log.i("111", "拖拽的view在BLUE中的位置:x =" + x + ",y=" + y);
                        break;
                    case DragEvent.ACTION_DROP:
                        Log.i("111", "釋放拖拽的view");
                        ImageView localState = (ImageView) event.getLocalState();
                        FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                        layoutParams.topMargin = (int) event.getY() - localState.getWidth() / 2;
                        layoutParams.leftMargin = (int) event.getX() - localState.getHeight() / 2;
                        ((ViewGroup) localState.getParent()).removeView(localState);
                        linearLayout.addView(localState, layoutParams);
                        imageView.setX(event.getX() - imageView.getWidth() / 2);
                        imageView.setY(event.getY() - imageView.getHeight() / 2);
                        break;
                }
                //是否響應拖拽事件,true響應,返回false只能接受到ACTION_DRAG_STARTED事件,後續事件不會收到
                return true;
            }
        });

ok講完了,就可以實現上面的效果了;
下面貼出完整程式碼:
MainActivity中:

package com.zhh.android;

import android.app.Activity;
import android.content.ClipData;
import android.content.Intent;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import android.view.DragEvent;
import android.view.HapticFeedbackConstants;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class MainActivity extends Activity {
    private ImageView imageView;
    private LinearLayout linearLayout;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView = (ImageView)findViewById(R.id.imageView);
        linearLayout = (LinearLayout)findViewById(R.id.linearLayout);

        imageView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                Intent intent = new Intent();
                ClipData clipData = ClipData.newIntent("label", intent);

                View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(v);
                v.startDrag(null, shadowBuilder, imageView, 0);
                //震動反饋
                v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
                return true;
            }
        });


        linearLayout.setOnDragListener(new View.OnDragListener() {
            @Override
            public boolean onDrag(View v, DragEvent event) {
                //v 永遠是設定該監聽的view,這裡即fl_blue
                String simpleName = v.getClass().getSimpleName();
//                Log.w(BLUE, "view name:" + simpleName);

                //獲取事件
                int action = event.getAction();
                switch (action) {
                    case DragEvent.ACTION_DRAG_STARTED:
                        Log.i("111", "開始拖拽");
                        imageView.setVisibility(View.INVISIBLE);
                        break;
                    case DragEvent.ACTION_DRAG_ENDED:
                        Log.i("111", "結束拖拽");
                        imageView.setVisibility(View.VISIBLE);
                        break;
                    case DragEvent.ACTION_DRAG_ENTERED:
                        Log.i("111", "拖拽的view進入監聽的view時");
                        break;
                    case DragEvent.ACTION_DRAG_EXITED:
                        Log.i("111", "拖拽的view離開監聽的view時");
                        break;
                    case DragEvent.ACTION_DRAG_LOCATION:
                        float x = event.getX();
                        float y = event.getY();
                        long l = SystemClock.currentThreadTimeMillis();
                        Log.i("111", "拖拽的view在BLUE中的位置:x =" + x + ",y=" + y);
                        break;
                    case DragEvent.ACTION_DROP:
                        Log.i("111", "釋放拖拽的view");
                        ImageView localState = (ImageView) event.getLocalState();
                        FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                        layoutParams.topMargin = (int) event.getY() - localState.getWidth() / 2;
                        layoutParams.leftMargin = (int) event.getX() - localState.getHeight() / 2;
                        ((ViewGroup) localState.getParent()).removeView(localState);
                        linearLayout.addView(localState, layoutParams);
                        imageView.setX(event.getX() - imageView.getWidth() / 2);
                        imageView.setY(event.getY() - imageView.getHeight() / 2);
                        break;
                }
                //是否響應拖拽事件,true響應,返回false只能接受到ACTION_DRAG_STARTED事件,後續事件不會收到
                return true;
            }
        });

    }


}

佈局檔案:activity_main中

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical"
    android:background="#4043f1"
    >

        <ImageView
            android:id="@+id/imageView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher" />



    <LinearLayout
        android:id="@+id/linearLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"

        android:orientation="vertical"
        >

    </LinearLayout>

</LinearLayout>

參考文章:
https://blog.csdn.net/Hubert_bing/article/details/79499654
原始碼下載:
https://download.csdn.net/download/zhaihaohao1/10890390