安卓拖拽总结(直接ontouch事件判断、DragViewHelper布局)

控件拖拽实现方式:
①根据控件的touch事件进行位置修改
②用ViewDragHelper做自定义控件

①介绍:

@Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:// 获取手指第一次接触屏幕
                    sx = (int) event.getRawX();
                    sy = (int) event.getRawY();
                    break;
                case MotionEvent.ACTION_MOVE:// 手指在屏幕上移动对应的事件
                    int x = (int) event.getRawX();
                    int y = (int) event.getRawY();
                    // 获取手指移动的距离
                    int dx = x - sx;
                    int dy = y - sy;
                    // 得到imageView最开始的各顶点的坐标
                    int l = v.getLeft();
                    int r = v.getRight();
                    int t = v.getTop();
                    int b = v.getBottom();
                    // 更改imageView在窗体的位置
                    v.layout(l + dx, t + dy, r + dx, b + dy);
                    // 获取移动后的位置
                    sx = (int) event.getRawX();
                    sy = (int) event.getRawY();
                    break;
                case MotionEvent.ACTION_UP:
                    break;
            }
            return true;
        }

依据不同手指动作进行相应处理:
①手指触摸屏幕:记录控件初始位置
②鼠标移动:先记录手指移动位置,接着按上次记录的位置将移动偏移量计算出来,偏移量+控件的长宽高等可以计算出控件新的layout位置,进行设置即可。

上述就是粗略实现了控件的拖拽,依据实际要求,在不同的事件进行添加逻辑即可。

②介绍:
首先这个用法主要是自己制造一个布局,该布局下的所有控件都可以拖动

public class DragView extends ConstraintLayout {
    ViewDragHelper viewDragHelper;

    public DragView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);


        viewDragHelper = ViewDragHelper.create(this, 1.f, new ViewDragHelper.Callback() {
            @Override
            public boolean tryCaptureView(@NonNull View child, int pointerId) {
                return true;
            }

            @Override
            public int clampViewPositionHorizontal(@NonNull View child, int left, int dx) {
                return left;
            }

            @Override
            public int clampViewPositionVertical(@NonNull View child, int top, int dy) {
                return top;
            }

            @Override
            public void onViewReleased(@NonNull View releasedChild, float xvel, float yvel) {
            }
        });
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return viewDragHelper.shouldInterceptTouchEvent(ev);
    }

    @SuppressLint("ClickableViewAccessibility")
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        viewDragHelper.processTouchEvent(event);
        return true;
    }
}

上述是最基础设置,要用ViewDragHelper拦截控件本身的触碰方法,交由其控制。

 <com.example.draghelper.DragView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <ImageView
            android:id="@+id/imageView3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            app:srcCompat="@drawable/right" />

        <ImageView
            android:id="@+id/imageView4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            app:srcCompat="@drawable/right" />
    </com.example.draghelper.DragView>

在布局中,该layout下的所有控件都可以自由拖动,重点实现让控件拖拽就是通过拦截其触碰事件完成,所以可以通过在拦截部分实现部分控件拖拽。
具体逻辑在onViewReleased等事件中完成。

并且在这个布局中的tryCaptureView会将View按序获取、存储,后续可以通过getChildAt(index)对特定的View进行逻辑设计。

拖拽注意事项:
有时添加一些操作,会导致拖拽的图片返回到初始位置,这通常因为拖拽后,底层的layoutparams更改了,即布局内的控件属性等进行了修改,这种情况需要重新给拖拽的View设置一次layoutParams。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

魔幻音

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值