MeiWidgetView进阶:仿头条小视频拖拽控件中的事件分发与拦截四重奏 MeiWidgetView进阶仿头条小视频拖拽控件中的事件分发与拦截四重奏【免费下载链接】MeiWidgetView一款汇总了郭霖鸿洋以及自己平时收集的自定义控件集合库小红书项目地址: https://gitcode.com/gh_mirrors/me/MeiWidgetViewMeiWidgetView 是汇总了郭霖、鸿洋及作者收藏的 Android 自定义控件集合库其中的仿头条小视频拖拽控件用一套事件分发与拦截的四重奏设计解决了拖拽手势、点击穿透、ViewPager 滑动冲突三大经典难题。本文带你用 5 分钟读懂这套设计哪怕你是控件新手也能学会思路。先认识仿头条小视频的交互体验点开列表页的任意一张小视频封面画面从封面位置放大到全屏在详情页向下滑动画面跟随手指缩小并下移松手超过阈值就甩回封面位置松手不够则弹回全屏——这就是头条小视频的核心体验。演示入口位于 MeiVideoDragListActivity.java点击封面时会通过getGlobalVisibleRect拿到封面的屏幕区域作为转场动画的终点坐标为什么不在 onInterceptTouchEvent 里写拦截逻辑按常规套路拦截滑动冲突应该在onInterceptTouchEvent里判断方向。但作者发现两个死结 子控件关注按钮、评论框等如果在ACTION_DOWN就消费了事件父布局永远收不到后续触摸事件想拦也拦不到反过来父布局一旦提前拦截子控件的点击又全部失效。于是作者把全部触摸逻辑统一收敛到dispatchTouchEvent中处理源码里的注释写得非常直白为了防止子控件 touch 消费事件导致父视图接受不到 touch 事件……顾最后统一在分发dispatchTouchEvent中处理见 DragRelativeLayout.java#L124-L126dispatchTouchEvent主流程在 DragRelativeLayout.java#L135-L161。第一重奏ACTION_DOWN 只做重置ACTION_DOWN时刻调用的 reset 方法 清空上一轮手势的全部状态状态字段作用mTouchLastX/Y手指上一个触点坐标mTouchOffsetX/Y累计偏移量用于方向判定mActionMoveCountMOVE 事件计数mIsInterceptEvent是否已判定为纵向拖拽重置完不消费事件而是super | true放行给子控件——先让子控件有机会消费点击自己只当旁观裁判。第二重奏ACTION_MOVE 方向判定与拖拽跟随move 方法 是整套设计的核心方向判定累计横向偏移|dx|≥ 纵向偏移|dy|时说明用户在横向滑动比如切 ViewPager返回true把事件让给子控件父布局主动让路纵向拖拽确认连续 1~2 帧纵向移动占优即置位mIsInterceptEvent回调onStartDrag跟手动画translationX跟手平移以屏幕底部为缩放中心setPivotY(getHeight())做等比缩小缩放到阈值以下后开始translationY下移模拟头条的先缩后落手感。第三重奏ACTION_UP 拦截假点击up 方法 做了一个关键防御如果ACTION_UP时偏移量为 0 且未发生拖拽说明这其实是一次普通点击返回true放行给子控件保证关注、评论按钮可点否则启动恢复动画或退出动画并消费事件防止松手瞬间误触按钮——这就是假点击拦截。第四重奏ACTION_DOWN 丢失的兜底转场动画结束后如果用户快速滑动屏幕系统可能丢掉ACTION_DOWN事件导致reset从未执行、状态错乱。作者在 DragRelativeLayout.java#L101-L102 增加mEventLostEnable标志位收到 MOVE 但检测到 DOWN 缺失时先补一次reset再break丢弃该帧四两拨千斤地兜住了兼容性问题。回调体系把手势语言翻译成业务行为拖拽细节全部封装在控件内部业务侧只需要实现 OnDragListener 的 7 个回调开始拖拽、释放、恢复/退出动画的开始与结束。以 MeiVideoDragFragment.java#L106-L153 为例开始拖拽时隐藏底部 UI退出动画结束时finish()页面配合 MeiVideoDragFragment.java#L95-L100 通过 EventBus 与列表页联动让封面在转场过程中同步滚动到指定位置。一句话总结这套分发四重奏可以浓缩为一句话DOWN 重置当裁判MOVE 判向让路或拦截UP 防误触放行点击DOWN 丢失兜底补状态。它不依赖onInterceptTouchEvent却同时满足了拖拽跟手、点击可用、横向滑动不冲突三个目标——这正是学习 Android 事件分发机制时最经典的一份实战样本 【免费下载链接】MeiWidgetView一款汇总了郭霖鸿洋以及自己平时收集的自定义控件集合库小红书项目地址: https://gitcode.com/gh_mirrors/me/MeiWidgetView创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考