前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ViewPager2实现内部Item的动态滚动

ViewPager2实现内部Item的动态滚动

作者头像
Petterp
发布2022-02-09 14:30:41
1.6K0
发布2022-02-09 14:30:41
举报
文章被收录于专栏:JetPack

需求决定起因

最近接到了一个需求,大概类似如下图所示的一个样式(省略了部分细节,不影响大概)。

我们这是一个视频播放页+详情页,考虑到简单快捷,就想到了一个 ViewPager2 就可以实现,简单又快捷,为自己点赞。一想到如此easy,瞬时笑出了猪叫。当然RecyclerView也可以,用一个仿抖音的那种 LayoutManager 就行,但是为什么不呢,因为涉及到了视频播放,手动去处理一些生命周期和懒加载,总是非常麻烦,而且ViewPager2本身就是基于 RecyclerView ,所以何乐而不为呢。

当然有些同学会说了,这个玩意自定义一个可滑动的ViewGroup就行啊,这个方案也可以。但是首先你要考虑的东西就很多,如果视频详情页超出一屏呢,也就是内部用了 RecyclerView或者NestedScrollView 呢,是不是还需要处理一下滑动冲突,当然这也不是很困难,内部拦截法就可以搞定。然后写完后,相应的加载回调是不是得自己再手动定义一个接口去伪造。比如不可见,页面加载,总体相对来说并不是那么容易。

就在我以为又可以摸鱼一个ViewPager2就可以搞定之时。突然,产品同学发了新指示,下意识预感不妙。

产品:得加一个第一次使用时的提示啊,要不然用户都不知道页面可以下滑呢?效果我发你了,你看看:

下图为我实现好的简单样式,大意体会即可。

好家伙,不按套路出牌啊,我故作深沉,实则稳如老狗( ViewPager2 不是有一个 fakeDragBy() 方法设置偏移量吗),这个有点麻烦,我得考虑考虑。

接下来不却知道自己要开启了啪啪打脸时刻,满心欢喜,太easy啊,ViewPager2 真香🤣!

打脸时刻

于是熟练的开分支,切分支,写demo,调用方法,走起!

先看一下这个方法。

fakeDragBy()

用于模拟手指拖动效果,需要先调用 beginFakeDrag() 开启,结束后,需要调用 endFakeDrag() 关闭。

既然有这个方法,那不就很简单吗,伪代码如下:

查看效果如下:

示例

我裂开了😨,为什么会这样,我就属性动画里调了一下而已,去看一下源码。

ViewPager2.fakeDragBy(x)

内部最终是调用了RecyclerView的 scrollBy() ,也就是相对滑动,哦原来如此,难怪调了一下,滑了这么远。

解决方法

既然如此,ViewPager2是基于RecyclerView,那么我去调用RecyclerView滚动不就行吗,思路如下:

  1. ViewPager2-> RecyclerView, RecyclerView默认是私有的,可以通过反射或者 getChildAt(0) 获取
  2. RecyclerView不支持 scrollTo() ,可以通过 LinearLayouManager 去滚动
  3. LinearLayoutManager-scrollToPositionWithOffset() 支持滚动到偏移位置

伪代码如下:

代码语言:javascript
复制
val layoutManager = (getChildAt(0) as? RecyclerView
        ?: return@apply).layoutManager as? LinearLayoutManager ?: return@apply
val oneAnimator = ValueAnimator.ofFloat(0f, -450f).apply {
    duration = 500
}
oneAnimator.addUpdateListener {
    layoutManager.scrollToPositionWithOffset(0, it.animatedValue as Int)
}
oneAnimator.start()

效果如最上面示例gif所示,这样就解决了ViewPager2-item动态滚动问题。

需要注意的点

就如我上面最开始分析时所述,如果详情页是可滑动的,那么就必须处理一下滑动冲突,相应的方式也很简单,使用内部拦截法,让滑动的View优先获得事件即可,当处于滑动View顶部时,再将事件还给父View.

后续

当然用ViewPager2去写仍然有种大材小用的感觉,毕竟只有两个item,所以,比较好的方式依然是使用自定义的滑动ViewGroup实现,所以我会在下篇博客来以一个自定义的方式来解决此问题。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 需求决定起因
  • 打脸时刻
  • 解决方法
  • 需要注意的点
  • 后续
相关产品与服务
云点播
面向音视频、图片等媒体,提供制作上传、存储、转码、媒体处理、媒体 AI、加速分发播放、版权保护等一体化的高品质媒体服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档