【Android 事件分发】ItemTouchHelper 源码分析 ( OnItemTouchListener 事件监听器源码分析 二 )(一)

简介: 【Android 事件分发】ItemTouchHelper 源码分析 ( OnItemTouchListener 事件监听器源码分析 二 )(一)

文章目录

Android 事件分发 系列文章目录

一、onTouchEvent 事件消费源码分析

1、onTouchEvent 方法

2、moveIfNecessary 方法

二、ItemTouchHelper 涉及到的本博客相关源码






一、onTouchEvent 事件消费源码分析


在上一篇博客 【Android 事件分发】ItemTouchHelper 源码分析 ( OnItemTouchListener 事件监听器源码分析 ) 主要分析了 给 RecyclerView 设置的 OnItemTouchListener 监听器的 onInterceptTouchEvent 触摸事件拦截方法 , 本篇博客中主要分析另外一个 触摸事件消费方法 onTouchEvent ;


在 onTouchEvent 事件消费 中 , 只处理 MotionEvent.ACTION_MOVE 事件 , 不处理其它事件 ;



1、onTouchEvent 方法


首先要获取操作的条目组件 ,


ViewHolder viewHolder = mSelected;


其中 mSelected 是在第一次按下时进行的赋值 , 有了 mSelected 值后 , 开始处理滑动事件 ;


如果没有获取到 mSelected , 则直接返回 ;


       

if (viewHolder == null) {
                return;
            }



如果当前处于拖动事件 MotionEvent.ACTION_MOVE , 则进行拖动事件处理 ;


拖动事件的核心是 moveIfNecessary 方法 , 该方法是处理滑动事件的核心方法


         

switch (action) {
                case MotionEvent.ACTION_MOVE: {
                  // 检查该操作是否在拖动 
                    // Find the index of the active pointer and fetch its position
                    if (activePointerIndex >= 0) {
                      // 记录修改偏移值 
                        updateDxDy(event, mSelectedFlags, activePointerIndex);
                        // 处理拖动事件
                        moveIfNecessary(viewHolder);
                        mRecyclerView.removeCallbacks(mScrollRunnable);
                        mScrollRunnable.run();
                        mRecyclerView.invalidate();
                    }
                    break;
                }



2、moveIfNecessary 方法


moveIfNecessary 方法中主要进行拖动事件判定 , 一般是拖动条目组件进行重新排序 ;


先获取开发者自定义的 Callback 中的 public float getMoveThreshold(@NonNull RecyclerView.ViewHolder viewHolder)方法返回值 , 如果开发者没有设置 , 就使用默认值 ;


该值的作用是 设置 拖动幅度 , 组件在宽度 / 高度 上移动超过该比例 , 就认为拖动触发, 执行拖动相关操作 ;


// 该方法就是 开发者 自定义 Callback 中的 
  // public float getMoveThreshold(@NonNull RecyclerView.ViewHolder viewHolder) 
  // 方法的作用是设置 拖动幅度
  // 组件在宽度 / 高度 上移动超过该比例 , 就认为拖动触发, 执行拖动相关操作
  // 拖动多少系数 , 才算完成 拖动操作 
        final float threshold = mCallback.getMoveThreshold(viewHolder);
        final int x = (int) (mSelectedStartX + mDx);
        final int y = (int) (mSelectedStartY + mDy);



获取到拖动系数后 , 使用了 threshold 系数 乘以 水平 / 垂直 方向上的条目组件 宽度 / 高度 ;


如果拖动比例超过在 水平 / 垂直 方向上的条目组件 宽度 / 高度 乘以 threshold 的值 , 则拖动判定成功 , 执行响应的方法 ;

如果拖动比例没有超过该值 , 说明没有触发拖动操作 , 直接返回 ;

   

// 在该判断中 , 使用了 threshold 系数 乘以 水平 / 垂直 方向上的条目组件宽度 ; 
        // 如果拖动比例超过在 水平 / 垂直 方向上的条目组件 宽度 / 高度 乘以 threshold 的值 
        // 则拖动判定成功 , 执行响应的方法 
        // 如果拖动比例没有超过该值 , 说明没有触发拖动操作 , 直接返回 
        if (Math.abs(y - viewHolder.itemView.getTop()) < viewHolder.itemView.getHeight() * threshold
                && Math.abs(x - viewHolder.itemView.getLeft())
                < viewHolder.itemView.getWidth() * threshold) {
            return;
        }


继续向后执行 , 说明拖动动作判定成功 , 执行拖动响应方法 , 即开发者自定义的 Callback 中的 onMove 方法 ;


public boolean onMove(@NonNull RecyclerView recyclerView,
                          @NonNull RecyclerView.ViewHolder viewHolder,
                          @NonNull RecyclerView.ViewHolder target)


先获取拖动的起始位置和目标位置 , 然后传入 onMove 方法 , 触发回调 ;


// 获取被拖动的目标位置
        final int toPosition = target.getAdapterPosition();
        // 获取被拖动的起始位置 
        final int fromPosition = viewHolder.getAdapterPosition();
  // 拖动判定成功 , 调用开发者实现的 Callback 的 
  // public boolean onMove(@NonNull RecyclerView recyclerView,
        //                  @NonNull RecyclerView.ViewHolder viewHolder,
        //                  @NonNull RecyclerView.ViewHolder target) 方法 
        // 一般是拖动交换数据 
        if (mCallback.onMove(mRecyclerView, viewHolder, target)) {
            // keep target visible
            mCallback.onMoved(mRecyclerView, viewHolder, fromPosition,
                    target, toPosition, x, y);
        }


目录
相关文章
|
4月前
|
XML Java Android开发
Android Studio App开发之捕获屏幕的变更事件实战(包括竖屏与横屏切换,回到桌面与切换到任务列表)
Android Studio App开发之捕获屏幕的变更事件实战(包括竖屏与横屏切换,回到桌面与切换到任务列表)
39 0
|
2天前
|
存储 Java Linux
Android系统获取event事件回调等几种实现和原理分析
Android系统获取event事件回调等几种实现和原理分析
20 0
|
4月前
|
小程序 JavaScript 前端开发
微信小程序(十七)小程序监听返回键跳转事件(安卓返回也适用)
onUnload:function(){ wx.redirectTo({ url: '../index/index' }) wx.navigateTo({ url: '../index/index' }) wx.switchTab({ url: '../../member/member' }) }
307 0
|
8月前
|
Android开发
Android PackageManagerService源码分析和APK安装原理详解
Android PackageManagerService源码分析和APK安装原理详解
206 1
|
4月前
|
XML Java Android开发
Android App事件交互Event之模仿京东App实现下拉刷新功能(附源码 可直接使用)
Android App事件交互Event之模仿京东App实现下拉刷新功能(附源码 可直接使用)
33 0
Android App事件交互Event之模仿京东App实现下拉刷新功能(附源码 可直接使用)
|
4月前
|
XML Java Android开发
Android App事件交互中辨别缩放与旋转手指的讲解与实战(附源码 可直接使用)
Android App事件交互中辨别缩放与旋转手指的讲解与实战(附源码 可直接使用)
37 0
|
4月前
|
XML Java Android开发
Android App事件交互中区分点击和长按动作以及识别手势滑动方向的讲解及实战(附源码 可直接使用)
Android App事件交互中区分点击和长按动作以及识别手势滑动方向的讲解及实战(附源码 可直接使用)
61 0
|
4月前
|
XML Java Android开发
Android App开发触摸事件中手势事件Event的分发流程讲解与实战(附源码 简单易懂)
Android App开发触摸事件中手势事件Event的分发流程讲解与实战(附源码 简单易懂)
43 0
|
4月前
|
XML 监控 Java
Android App开发之事件交互Event中检测软键盘和物理按键讲解及实战(附源码 演示简单易懂)
Android App开发之事件交互Event中检测软键盘和物理按键讲解及实战(附源码 演示简单易懂)
129 0
|
8月前
|
Android开发
Android 获取include标签中的控件属性并设置事件
Android 获取include标签中的控件属性并设置事件
138 0