您当前的位置: 首页 >  android

韩曙亮

暂无认证

  • 2浏览

    0关注

    1068博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

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

韩曙亮 发布时间:2021-07-15 15:37:18 ,浏览量:2

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.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
关注
打赏
1663594092
查看更多评论
0.7985s