文章目录
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.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(); } }