【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 设置一个 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.ItemDecoration
implements 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.ItemDecoration
mRecyclerView.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 attached
final 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.
*
* 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.
*
* @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
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?