自定义可拖拽View(工具类ViewDragHelper的用法)


android提供了GestureDetector

这个类用于常用手势识别, 如单击、双击、滑动等; 对于拖拽手势的分析识别并不理性,

因此support-v4包提供了一个工具类ViewDragHelper, 使用此工具类可以轻松实现可拖拽View(准确的说应该是支持拖拽的View容器), 


闲话少说, 请看代码: 


 DragContainerLayout.java

/**
 * ViewDragHelper的用法
 * 1. ViewDragHelper.create()创建实例
 * 2. 初始化callback
 * 3. 将当前ViewGroup的onInterceptTouchEvent和onTouchEvent事件委托给ViewDragHelper处理
 * 4. 处理拖拽view的边界(在callback中的clampViewPositionHorizontal和clampViewPositionVertical方法中处理)
 */
public class DragContainerLayout extends LinearLayout{

    private ViewDragHelper mViewDragHelper;

    public DragContainerLayout(Context context) {
        super(context);
        initViewDragHelper();
        GestureDetector
    }

    public DragContainerLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        initViewDragHelper();
    }

    public DragContainerLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initViewDragHelper();
    }

    public DragContainerLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initViewDragHelper();
    }

    private void initViewDragHelper() {
        //ViewDragHelper.Callback是一个抽象类, 里面有更多的处理, 将需要处理的方法重写就可以了
        mViewDragHelper = ViewDragHelper.create(this, 1.0f, new ViewDragHelper.Callback() {
            @Override
            public boolean tryCaptureView(View child, int pointerId) {
                Log.e("abc", "pointerId=" + pointerId);

                //第3个view不能截取事件 (也就是不能拖拽)
                if(getChildCount() >= 3) {
                    if(child == getChildAt(2)) {
                        return false;
                    }
                }

                return true; //true表示child可以拖拽, false标示child不能拖拽
            }

            @Override
            public int clampViewPositionHorizontal(View child, int left, int dx) {
                final int leftBound = getPaddingLeft();
                final int rightBound = getWidth() - child.getWidth() - getPaddingRight();

//                int newLeft = left;
//                if(left < leftBound) newLeft = leftBound;
//                if(left > rightBound) newLeft = rightBound;

                //词句等价于上面的三句
                int newLefth = Math.min(Math.max(left, leftBound), rightBound);
                return newLefth;
            }

            @Override
            public int clampViewPositionVertical(View child, int top, int dy) {
                final int topBound = getPaddingTop();
                final int bottomBound = getHeight() - child.getHeight() - getPaddingBottom();

                int newTop = Math.min(bottomBound, Math.max(topBound, top));
                return newTop;
            }
        });
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        final int action = MotionEventCompat.getActionMasked(ev);
        if(action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
            mViewDragHelper.cancel();
            return false;
        }

        return mViewDragHelper.shouldInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mViewDragHelper.processTouchEvent(event);
        return true;
    }
}



布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <com.stone.android_demo2.DragContainerLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:gravity="center"
        android:paddingTop="60dp"
        android:paddingLeft="0dp"
        android:paddingBottom="0dp"
        android:paddingRight="30dp">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello"
            android:padding="10dp"
            android:background="#4400ccaa"
            android:layout_marginTop="10dp"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="哈哈哈哈哈"
            android:padding="10dp"
            android:background="#4400ccaa"
            android:layout_marginTop="10dp"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="wakaka"
            android:padding="10dp"
            android:background="#4400ccaa"
            android:layout_marginTop="10dp"/>

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hi, hi, you you !"
            android:padding="10dp"
            android:background="#4400ccaa"
            android:layout_marginTop="10dp"/>
    </com.stone.android_demo2.DragContainerLayout>
</LinearLayout>

创建一个Activity, 使用上述布局, 运行, 试试拖拽TextView 大笑










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值