Android 事件分发 系列文章目录

【Android 事件分发】事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 )
【Android 事件分发】事件分发源码分析 ( Activity 中各层级的事件传递 | Activity -> PhoneWindow -> DecorView -> ViewGroup )
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 一 )
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 二 )
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 三 )
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 四 | View 事件传递机制 )
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 五 )
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 六 )
【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 七 )

【Android 事件分发】ItemTouchHelper 简介 ( 拖动/滑动事件 | ItemTouchHelper.Callback 回调 )
【Android 事件分发】ItemTouchHelper 实现侧滑删除 ( 设置滑动方向 | 启用滑动操作 | 滑动距离判定 | 滑动速度判定 | 设置动画时间 | 设置侧滑触发操作 )
【Android 事件分发】ItemTouchHelper 实现拖动排序 ( 设置滑动方向 | 启启用长按拖动功能 | 拖动距离判定 | 设置拖动触发操作 )

【Android 事件分发】ItemTouchHelper 事件分发源码分析 ( 绑定 RecyclerView )


文章目录

  • Android 事件分发 系列文章目录
  • 一、ItemTouchHelper 事件分发源码分析入口
  • 二、ItemTouchHelper 绑定 RecyclerView 源码分析
    • 1、ItemTouchHelper.attachToRecyclerView 方法分析
    • 2、ItemTouchHelper.setupCallbacks 方法分析
    • 3、RecyclerView.ItemDecoration 源码分析
  • 三、博客资源

一、ItemTouchHelper 事件分发源码分析入口


ItemTouchHelper 使用时 , 是为 ItemTouchHelper 设置一个 RecyclerView 列表 , 不是给 RecyclerView 设置一个 ItemTouchHelper ;

        //4. 添加拖动/滑动事件Callback callback = new Callback(adapter);mItemTouchHelper = new ItemTouchHelper(callback);mItemTouchHelper.attachToRecyclerView(recycler_view);

因此 , 事件分发的核心处理逻辑 , 都在 ItemTouchHelper 中实现 , 要研究其中的事件分发原理 , 主要分析 ItemTouchHelper 中的源码即可 ;

二、ItemTouchHelper 绑定 RecyclerView 源码分析


1、ItemTouchHelper.attachToRecyclerView 方法分析

ItemTouchHelper.attachToRecyclerView 方法 , 用于将 ItemTouchHelper 与 RecyclerView 进行绑定 ; 以该方法为入口 , 进行源码分析 ;

在初始化之前 , 判定该 RecyclerView 是否已经绑定 , 如果已经绑定 , 不再执行该绑定方法 ;

        if (mRecyclerView == recyclerView) {// 判定是否已经绑定 , 如果已经绑定 , 不再执行绑定方法 return; // nothing to do}

然后清空之前原有的回调 , 其中涉及到 destroyCallbacks 方法 , 该 destroyCallbacks 方法与 setupCallbacks 方法相对应 , 一个是设置 , 一个是销毁 ;

        if (mRecyclerView != null) {// 使用前 , 清空所有的回调 // 使用前重置 destroyCallbacks();}

最后 , 设置当前的 mRecyclerView 成员为绑定的 RecyclerView 列表 , 并调用 setupCallbacks 方法 , 为 ItemTouchHelper 设置回调 ;

在 setupCallbacks 中 , 调用 RecyclerView.addOnItemTouchListener 方法 , 为 RecyclerView 设置了触摸监听器 , 该触摸监听器是定义在 ItemTouchHelper 中的成员变量 private final OnItemTouchListener mOnItemTouchListener ;

        // 添加了每个条目上的触摸监听器 mOnItemTouchListener // 该监听器是定义在 ItemTouchHelper 中的成员变量 mRecyclerView.addOnItemTouchListener(mOnItemTouchListener);

ItemTouchHelper 相关源码 :

public class ItemTouchHelper extends RecyclerView.ItemDecorationimplements RecyclerView.OnChildAttachStateChangeListener {private final OnItemTouchListener mOnItemTouchListener = new OnItemTouchListener() {}/*** Attaches the ItemTouchHelper to the provided RecyclerView. If TouchHelper is already* attached to a RecyclerView, it will first detach from the previous one. You can call this* method with {@code null} to detach it from the current RecyclerView.** @param recyclerView The RecyclerView instance to which you want to add this helper or*                     {@code null} if you want to remove ItemTouchHelper from the current*                     RecyclerView.*/public void attachToRecyclerView(@Nullable RecyclerView recyclerView) {if (mRecyclerView == recyclerView) {// 判定是否已经绑定 , 如果已经绑定 , 不再执行绑定方法 return; // nothing to do}if (mRecyclerView != null) {// 使用前 , 清空所有的回调 // 使用前重置 destroyCallbacks();}// 设置当前的 mRecyclerView 成员为绑定的 RecyclerView 列表mRecyclerView = recyclerView;if (recyclerView != null) {final Resources resources = recyclerView.getResources();mSwipeEscapeVelocity = resources.getDimension(R.dimen.item_touch_helper_swipe_escape_velocity);mMaxSwipeVelocity = resources.getDimension(R.dimen.item_touch_helper_swipe_escape_max_velocity);// 该方法是核心方法 // 为 ItemTouchHelper 绑定 ItemTouchHelper.Callback setupCallbacks();}}// 该方法与 destroyCallbacks 方法相对应private void setupCallbacks() {// 配置相关  ViewConfiguration vc = ViewConfiguration.get(mRecyclerView.getContext());mSlop = vc.getScaledTouchSlop();// 设置 RecyclerView 条目中的装饰 , 可以在条目组件 底部 上层 绘制 Canvas 图形 // ItemTouchHelper 继承 RecyclerView.ItemDecorationmRecyclerView.addItemDecoration(this);// 添加了每个条目上的触摸监听器 mOnItemTouchListener // 该监听器是定义在 ItemTouchHelper 中的成员变量 mRecyclerView.addOnItemTouchListener(mOnItemTouchListener);mRecyclerView.addOnChildAttachStateChangeListener(this);startGestureDetection();}// 该方法与 setupCallbacks 方法相对应// 清空所有的回调 , 重置 RecyclerView private void destroyCallbacks() {mRecyclerView.removeItemDecoration(this);mRecyclerView.removeOnItemTouchListener(mOnItemTouchListener);mRecyclerView.removeOnChildAttachStateChangeListener(this);// clean all attachedfinal int recoverAnimSize = mRecoverAnimations.size();for (int i = recoverAnimSize - 1; i >= 0; i--) {final RecoverAnimation recoverAnimation = mRecoverAnimations.get(0);mCallback.clearView(mRecyclerView, recoverAnimation.mViewHolder);}mRecoverAnimations.clear();mOverdrawChild = null;mOverdrawChildPosition = -1;releaseVelocityTracker();stopGestureDetection();}
}

2、ItemTouchHelper.setupCallbacks 方法分析

在 ItemTouchHelper.setupCallbacks 方法中 , 调用了

mRecyclerView.addItemDecoration(this);

方法 , 为当前的 RecyclerView 设置条目装饰 , 该装饰可以在条目组件 底部 上层 绘制 Canvas 图形 , 具体的方法如下 :

public class RecyclerView extends ViewGroup implements ScrollingView,NestedScrollingChild2, NestedScrollingChild3 {/*** Add an {@link ItemDecoration} to this RecyclerView. Item decorations can* affect both measurement and drawing of individual item views.** <p>Item decorations are ordered. Decorations placed earlier in the list will* be run/queried/drawn first for their effects on item views. Padding added to views* will be nested; a padding added by an earlier decoration will mean further* item decorations in the list will be asked to draw/pad within the previous decoration's* given area.</p>** @param decor Decoration to add* @param index Position in the decoration chain to insert this decoration at. If this value*              is negative the decoration will be added at the end.*/public void addItemDecoration(@NonNull ItemDecoration decor, int index) {if (mLayout != null) {mLayout.assertNotInLayoutOrScroll("Cannot add item decoration during a scroll  or"+ " layout");}if (mItemDecorations.isEmpty()) {setWillNotDraw(false);}// 将多个 ItemDecoration 添加到 mItemDecorations 集合中if (index < 0) {mItemDecorations.add(decor);} else {mItemDecorations.add(index, decor);}markItemDecorInsetsDirty();// 开始进行绘制 requestLayout();}
}

3、RecyclerView.ItemDecoration 源码分析

ItemDecoration 是抽象类 , 核心逻辑必须由子类实现后才可以使用 ;

void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull State state) 方法是绘制方法 , 在该方法中调用了 void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent) 方法 ,

    public abstract static class ItemDecoration {public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull State state) {onDraw(c, parent);}@Deprecatedpublic void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent) {}}

参考 Android 官方提供的 RecyclerView.ItemDecoration 的实现类 DividerItemDecoration , 该类中重写了 onDraw 方法 , 其中调用了 drawVertical 绘制垂直分割线 , 调用了 drawHorizontal 方法绘制水平分割线 ;

public class DividerItemDecoration extends RecyclerView.ItemDecoration {@Overridepublic void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {if (parent.getLayoutManager() == null || mDivider == null) {return;}if (mOrientation == VERTICAL) {// 绘制垂直分割线drawVertical(c, parent);} else {// 绘制水平分割线drawHorizontal(c, parent);}}
}

在上述 drawVertical 和 drawHorizontal 方法中 , 利用 Canvas 进行绘图 ;

在 RecyclerView.ItemDecoration 中 , 不仅仅只能绘制分割线 , 可以绘制任何图形 , 图片 , 颜色 , 与自定义组件绘制功能一样强大 ;

三、博客资源


博客资源 :

  • GitHub 地址 : https://github.com/han1202012/001_RecyclerView

【Android 事件分发】ItemTouchHelper 事件分发源码分析 ( 绑定 RecyclerView )相关推荐

  1. 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 七 )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

  2. 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 六 )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

  3. 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 五 )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

  4. 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 四 | View 事件传递机制 )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

  5. 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 三 )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

  6. 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 二 )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

  7. 【Android 事件分发】事件分发源码分析 ( ViewGroup 事件传递机制 一 )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

  8. 【Android 事件分发】事件分发源码分析 ( Activity 中各层级的事件传递 | Activity -> PhoneWindow -> DecorView -> ViewGroup )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) [Andr ...

  9. 【Android 事件分发】事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 )

    Android 事件分发 系列文章目录 [Android 事件分发]事件分发源码分析 ( 驱动层通过中断传递事件 | WindowManagerService 向 View 层传递事件 ) 文章目录 ...

最新文章

  1. java中execution的作用_一文初步了解Java虚拟机
  2. 丢失控制文件,有旧的备份控制文件,之后有drop表空间和create表空间的操作恢复。...
  3. 【译】node js event loop part 1.1
  4. Codeforces 1305F Kuroni and the Punishment (随机化)
  5. java应用cpu使用率过高问题排查
  6. python 连通区域_python skimage 连通性区域检测方法
  7. VAE【变分自编码器】
  8. eclipse工程运行正常但是工程有红叉的问题
  9. ​云原生:重新定义云时代的技术标准 | 凌云时刻
  10. 太阳高度角计算题_正午太阳高度变化及计算(模拟题组)
  11. 自举电容充电回路分析
  12. USB对拷线Linux,绿联USB对拷线升级软件方法说明
  13. 设CPU共有16根地址线,8根数据线,并用MREQ (低电平有效) .作访存控制信号,R/W作读写命令信号(高电平为读,,低电平为写)。
  14. 线性代数及矩阵论(七)
  15. python我的世界给予物品指令_我的世界给予物品指令大全 | 手游网游页游攻略大全...
  16. 关于kindle使用的文章
  17. python (语音)信号拆分为数据块,计算短期能量和过零率
  18. Pytorch tutorial pytorch 入门
  19. OpenCV手掌识别
  20. spm12预处理步骤及知识点总结

热门文章

  1. cocos2d-x 帧动画学习
  2. [摘录]遇见未知的自己(一)
  3. 开源自己写的Library到github,让别人或自己的项目依赖
  4. 并发Goroute、定时器、信号处理、单元测试
  5. poj1018 Communication System (有道翻译完全拯救不了)
  6. ASP.NET Core 中文文档 第三章 原理(12)托管
  7. 使用sed,awk将love转换成LOVE,将CHINA转换成china
  8. 30分钟?不需要,轻松读懂IL
  9. JS 设计模式四 -- 模块模式
  10. 登录状态保持Session/Cookie