进一步使用 RecyclerView + SnapHelper 代替 ViewPager

当 PagerSnapHelper 出现后,使用 RecyclerView 代替 ViewPager 越来越可行了。 RecyclerView 的动态更新是基础功能,而 ViewPager 的动态更新一直是这个控件的痛点。

使用 RecyclerView + SnapHelper 展示简单的 View 翻页是没有问题,不过想进一步实现 RecyclerView 动态显示 Fragment 就遇到各种组件的缺失。

一. ViewHolder 显示 Fragment

要在 RecyclerView.ViewHolder 内显示 Fragment。首先需要一个类似 android.support.v4.app.FragmentPagerAdapter 管理 Fragment 的动态绑定的 RecyclerView.Adapter。

使用 FragmentManager 和 FragmentTransaction 添加 Fragment 时,需要页面(FragmentContainer) 中一个 ViewGroup 的 Id 进行绑定。RecyclerView.ViewHolder 的几个生命周期对于我们怎样绑定 Fragment 很重要:

具体代码参见 FragmentRecyclerAdapter.java

  1. onCreateViewHolder

    基于 FrameLayout 创建空的 ViewHolder

  2. onBindViewHolder

    基于 ViewCompat.generateViewId() 和当前 position 对 ViewHolder 中 itemView (FrameLayout)重新 setId, 保证 Id 唯一。

  3. onViewAttachedToWindow

    当 ViewHolder 开始在页面显示时,对 Fragment 进行 add 或 attach 以及 setUserVisibleHint 等处理。 注意,在 onBindViewHolder 时,不能马上操作 FragmentTransaction,因为 ViewHolder 的 itemView 还没有被添加到 ViewTree 中,FragmentContainer 是找不到设置的 Id 的

  4. onViewDetachedFromWindow

    ViewHolder 离屏不显示,只对 Fragment 进行 setUserVisibleHint 等操作,保证 Fragment 生命周期正确。

  5. onViewRecycled

    ViewHolder 开始被回收复用时,对绑定在 itemView 上的 Fragment 进行 detach 。

二. RecyclerView 滚动监听 SnapHelper 选中页面

我们还缺少 ViewPager.OnPageChangeListener 这样方便的回调。

  1. onPageScrollStateChanged(int state)
  2. onPageScrolled(int position, float positionOffset, int positionOffsetPixels)
  3. onPageSelected(int position)

具体代码参见 SnapPageScrollListener.java

继承 RecyclerView.OnScrollListener,其中 onScrollStateChanged(RecyclerView recyclerView, int newState) 已经实现了第 1 个回调。 剩下两个回调需要在 onScrolled(RecyclerView recyclerView, int dx, int dy) 计算实现。

SnapHelper 的 findSnapViewcalculateDistanceToFinalSnap 能帮助我们确定选中 View 的位置和距离。 避免使用如 LinearLayoutManager.findFirstVisibleItemPosition 等实现类方法来计算。

只是在滚动中,例如 A、B页面滚动到 50% 之后时, findSnapView 命中的目标会 A 切换到 B。与 ViewPager 中 A 页面一定是滑动到 100% 才从 A 切换到 B 有些出入。

三. TabLayout 控件支持

现有的 TabLayout 开源控件一般基于 ViewPager 的数据源和滚动接口来实现。

例如 SmartTabLayout , Fork一份,将原控件中 ViewPager 的接口和数据源剥离,传入 RecyclerView 和 SnapHelper,配合上面的 SnapPageScrollListener 就能很快改装成支持 RecyclerView 的 TabLayout。 同时还能支持 RecyclerView 的动态更新。

具体代码参见 SmartTabLayout2.java


最后整个配套使用如下:

项目地址: RecyclerPager


另外,有两个招聘广告,感谢查看了解:

【Android开发工程师】www.lagou.com/jobs/180879…

【前端开发工程师】www.lagou.com/jobs/415543…

简历备注【掘金】 ?

转载于:https://juejin.im/post/5bde533751882516d155269b

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值