Android ViewDragHelper使用及原理

本文详细解析了Android中ViewDragHelper的初始化、事件拦截处理和拖动事件处理过程,包括如何设置拖动边界、启动拖动、处理拖动、释放拖动以及滚动效果。通过对ViewDragHelper的源码分析,介绍了如何利用它实现View的拖拽和侧滑功能,以及在实际应用中的操作技巧。
摘要由CSDN通过智能技术生成


ViewDragHelper类,是用来处理View边界拖动相关的类,比如我们这里要用的例子—侧滑拖动关闭页面(类似微信),该功能很明显是要处理在View上的触摸事件,记录触摸点、计算距离、滚动动画、状态回调等,如果我们自己手动实现自然会很麻烦还可能出错,而这个类会帮助我们大大简化工作量。

该类是在Support包中提供,所以不会有系统适配问题,下面我们就来看看他的原理和使用吧。

1.初始化

private ViewDragHelper(Context context, ViewGroup forParent, Callback cb) {
   
        ...
        mParentView = forParent;//BaseView
        mCallback = cb;//callback
        final ViewConfiguration vc = ViewConfiguration.get(context);
        final float density = context.getResources().getDisplayMetrics().density;
        mEdgeSize = (int) (EDGE_SIZE * density + 0.5f);//边界拖动距离范围
        mTouchSlop = vc.getScaledTouchSlop();//拖动距离阈值
        mScroller = new OverScroller(context, sInterpolator);//滚动器
    }
  • mParentView是指基于哪个View进行触摸处理

  • mCallback是触摸处理的各个阶段的回调

  • mEdgeSize是指在边界多少距离内算作拖动,默认为20dp

  • mTouchSlop指滑动多少距离算作拖动,用的系统默认值

  • mScroller是View滚动的Scroller对象,用于处理释触摸放后,View的滚动行为,比如滚动回原始位置或者滚动出屏幕

2.拦截事件处理

该类提供了boolean shouldInterceptTouchEvent(MotionEvent)方法,通常我们需要这么写:

override fun onInterceptTouchEvent(ev: MotionEvent?) =
            dragHelper?.shouldInterceptTouchEvent(ev) ?: super.onInterceptTouchEvent(ev)

该方法用于处理mParentView是否拦截此次事件

public boolean shouldInterceptTouchEvent(MotionEvent ev) {
   
        ...
        switch (action) {
   
            ...
            case MotionEvent.ACTION_MOVE: {
   
                if (mInitialMotionX == null || mInitialMotionY == null) break;
                // First to cross a touch slop over a draggable view wins. Also report edge drags.
                final int pointerCount = ev.getPointerCount();
                for (int i = 0; i < pointerCount; i++) {
   
                    final int pointerId = ev.getPointerId(i);
                    // If pointer is invalid then skip the ACTION_MOVE.
                    if (!isValidPointerForActionMove(pointerId)) continue;
                    final float x = ev.getX(i);
                    final float y = ev.getY(i);
                    final float dx = x - mInitialMotionX[pointerId];
                    final float dy = y - mInitialMotionY[pointerId];
                    final View toCapture = findTopChildUnder((int) x, (int) y);
                    final boolean pastSlop = toCapture != null && checkTouchSlop(toCapture, dx, dy);
                    ...
                    //判断pointer的拖动边界
                    reportNewEdgeDrags(dx, dy, pointerId);
                    ...
                }
                saveLastMotion(ev);<
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值