ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

MicroReader频道拖拽排序实现:ItemTouchHelper玩转RecyclerView实战

MicroReader频道拖拽排序实现:ItemTouchHelper玩转RecyclerView实战 MicroReader频道拖拽排序实现ItemTouchHelper玩转RecyclerView实战【免费下载链接】MicroReader一个小而美的阅读客户端项目地址: https://gitcode.com/gh_mirrors/mi/MicroReaderMicroReader 是一款小而美的阅读客户端聚合了微信、果壳、知乎、视频、IT之家等多个内容频道。它内置了一个非常实用的频道管理页支持对已显示频道进行拖拽排序甚至可以把频道在已显示与未显示两个分区之间来回拖动。本文就以 MicroReader 为案例带你一步步拆解它是如何用ItemTouchHelper玩转RecyclerView实现丝滑的频道拖拽排序功能的。即使你是刚接触 Android 列表开发的新手跟着这篇实战指南走一遍也能完全看懂其中的套路。一、先认识 MicroReader 的频道管理功能MicroReader 的频道管理入口在侧边栏进入后你会看到两栏列表上面是我的频道已显示下面是更多频道未显示。每条频道带一个小拖拽手柄按住即可拖动。支持的操作场景有四种已显示频道内部调整顺序已显示频道拖回未显示区未显示频道拖入已显示区未显示频道内部调整顺序用户退出页面时新的排序会写入本地存储下次启动依然生效——排序结果被 MainActivity 读取后会按顺序生成导航菜单与 Fragment。整套逻辑的核心就藏在下面这几个文件里拖拽回调ItemDragHelperCallback.java移动监听接口OnItemMoveListener.java频道适配器ChannelAdapter.java频道管理页ChangeChannelActivity.java排序持久化ChangeChannelPresenterImpl.java二、为什么选 ItemTouchHelper三条理由实现列表拖拽有很多方案MicroReader 选择了官方推荐组件ItemTouchHelper属于android.support.v7.widget.helper包。它的优势非常明显开箱即用只需继承ItemTouchHelper.Callback重写几个方法就能获得拖拽时的自动换位、自动滚动、抬升动画等效果。与 RecyclerView 深度集成通过attachToRecyclerView()一行代码绑定无需自己处理触摸事件分发。可精细控制拖拽方向、是否支持长按拖拽、是否支持滑动删除全都可以通过方法开关灵活度极高。三、实战第一步自定义 Callback 控制拖拽方向频道管理页在 ChangeChannelActivity.java 的initView()中完成初始化核心只有三步创建回调、创建 Helper、绑定列表。ItemDragHelperCallback callback new ItemDragHelperCallback(); final ItemTouchHelper helper new ItemTouchHelper(callback); helper.attachToRecyclerView(mRv);真正的戏法在 ItemDragHelperCallback.java 里。它通过getMovementFlags()动态判断布局管理器类型如果是GridLayoutManager或StaggeredGridLayoutManager网格布局就允许上下左右四个方向拖拽如果是普通的线性布局则只允许上下拖拽。这个细节非常贴心保证了不同布局下拖拽的手感都是自然的。同时它主动关闭了两个默认开关isLongPressDragEnabled()返回false——不启用长按拖拽改由手动触发后面会讲isItemViewSwipeEnabled()返回false——关闭滑动删除因为频道列表不需要滑动功能。四、实战第二步数据搬运的桥梁 OnItemMoveListener拖拽时视图会移动但数据必须自己搬。MicroReader 定义了一个极简的接口 OnItemMoveListener.java只暴露一个方法public interface OnItemMoveListener { void onItemMove(int fromPosition, int toPosition); }在回调的onMove()方法里它不直接操作数据而是判断适配器是否实现了该接口然后调用listener.onItemMove(from, to)把位置信息甩锅给适配器处理。这种接口回调 适配器自处理的设计让回调类保持纯净职责非常清晰。五、实战第三步搞定显示/未显示两种分区的四种移动这是整个实现中最精彩的部分。频道列表用getItemViewType()区分三种条目Header分区标题、已显示频道、未显示频道位置 0 和mSavedChannel.size() 1是固定的两个 Header。在 ChannelAdapter.java 的onItemMove()中通过判断起点和终点位置分四路处理已显示区内移动直接移除再插入mSavedChannel调用notifyItemMoved()已显示 → 未显示从已显示集合移除插入未显示集合头部未显示 → 已显示从未显示集合移除插入已显示集合头部未显示区内移动与情况 1 对称处理。得益于notifyItemMoved()自带动画拖拽过程中列表的换位动画完全由系统驱动代码量极少观感却非常流畅。虽然这里位置计算用了不少下标偏移因为中间隔着 Header但逻辑分支注释清晰读起来并不困难。六、实战第四步用拖拽手柄手动触发 startDrag因为关闭了长按拖拽MicroReader 改为点击即拖在onCreateViewHolder里给整个条目和右侧的拖拽手柄图标mIvDrag都设置了OnTouchListener触摸时直接调用mItemTouchHelper.startDrag(channelViewHolder);startDrag()是手动开始拖拽的官方 API配合自定义的ItemDragHelperCallback比长按触发更符合用户直觉——看到手柄就知道这里能拖。七、实战第五步排序结果的持久化保存拖拽排序如果退出就失效那体验就大打折扣。MicroReader 用 SharedPreferences 解决了这个问题保存在 ChangeChannelPresenterImpl.java 的saveChannel()中把频道枚举名用逗号拼接成字符串存入SAVED_CHANNEL读取getChannel()启动时读取字符串并拆分成列表不在列表中的频道自动归入未显示分区生效MainActivity 读取同一份配置按顺序生成侧边栏菜单和对应的内容 Fragment频道拖拽排序的结果即刻反映到主界面。这套枚举名序列化的方案虽然简单但胜在清晰可靠非常适合小型应用。八、总结这套实现能学到什么回顾 MicroReader 的频道拖拽排序实战核心知识点可以浓缩成一句话回调管手势接口传位置适配器搬数据Preferences 存结果。四个角色各司其职构成了一个完整且可复用的拖拽排序闭环。如果你想在自己的项目里复刻这套能力只需要记住以下清单✅ 自定义ItemTouchHelper.Callback控制方向与开关✅ 定义OnItemMoveListener回调接口✅ 在onItemMove()中完成数据集合的增删改✅ 用startDrag()实现手柄/点击触发✅ 退出页面时保存排序启动时恢复MicroReader 整体代码结构清晰MVP 分层规范非常适合阅读学习。如果你想看完整的实现细节可以 clone 仓库到本地慢慢研究或者直接在项目里搜索ItemTouchHelper关键词很快就能定位到这套拖拽排序的完整链路。动手试试吧用RecyclerView ItemTouchHelper给你的应用也加一个顺手的频道拖拽排序功能【免费下载链接】MicroReader一个小而美的阅读客户端项目地址: https://gitcode.com/gh_mirrors/mi/MicroReader创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表