【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);
        }


目录
相关文章
|
2月前
|
Android开发
Android面试高频知识点(1) 图解Android事件分发机制
Android面试高频知识点(1) 图解Android事件分发机制
|
2月前
|
Android开发
Android面试高频知识点(1) 图解 Android 事件分发机制
Android面试高频知识点(1) 图解 Android 事件分发机制
45 1
|
2月前
|
XML 前端开发 Android开发
Android面试高频知识点(1) 图解Android事件分发机制
Android面试高频知识点(1) 图解Android事件分发机制
Android面试高频知识点(1) 图解Android事件分发机制
|
2月前
|
Android开发
Android 事件分发机制详细解读
Android 事件分发机制详细解读
44 5
|
4月前
|
图形学 Android开发
小功能⭐️Unity调用Android常用事件
小功能⭐️Unity调用Android常用事件
|
4月前
|
Android开发
Android面试高频知识点(1) 图解 Android 事件分发机制
在Android开发中,事件分发机制是一块Android比较重要的知识体系,了解并熟悉整套的分发机制有助于更好的分析各种点击滑动失效问题,更好去扩展控件的事件功能和开发自定义控件,同时事件分发机制也是Android面试必问考点之一,如果你能把下面的一些事件分发图当场画出来肯定加分不少。废话不多说,总结一句:事件分发机制很重要。
202 9
|
4月前
|
开发工具 Android开发
Android项目架构设计问题之组件A通知组件B某个事件的发生如何解决
Android项目架构设计问题之组件A通知组件B某个事件的发生如何解决
43 0
|
6月前
|
Android开发
39. 【Android教程】触摸事件分发
39. 【Android教程】触摸事件分发
48 2
|
6月前
|
XML Android开发 数据格式
37. 【Android教程】基于监听的事件处理机制
37. 【Android教程】基于监听的事件处理机制
92 2
|
7月前
|
存储 Java Linux
Android系统获取event事件回调等几种实现和原理分析
Android系统获取event事件回调等几种实现和原理分析
474 0