ViewPager2&TabLayout:拓展出一个文本选中放大效果

Posted 让开,我要吃人了

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ViewPager2&TabLayout:拓展出一个文本选中放大效果相关的知识,希望对你有一定的参考价值。

ViewPager2正式推出已经一年多了,虽然不如3那样新潮,但是也不如老前辈ViewPager那样有众多开源库拥簇,比如它的灵魂伴侣TabLayout明显后援不足,好在TabLayout自身够硬!

ViewPager2灵魂伴侣是官方提供的:

com.google.android.material.tabs.TabLayout

TabLayout 利用其良好的设计,使得自定义非常容易。

像匹配ViewPager的优秀开源库FlycoTabLayout的效果,使用TabLayout都能比较容易的实现:

FlycoTabLayout 演示

实现上图中的几个常用效果TabLayout 仅需在xml重配置即可

不过稍微不同的是,上图中第二第三栏选中后的字体是有放大效果的。

这是利用TabLayout.TabcustomView属性达到的。下文便是实现的思路与过程记录。

正文

思路拆解:

  • 介于此功能耦合点仅仅是TabLayoutMediator,选择使用拓展包装TabLayoutMediator,轻量且无侵入性,API还便捷
  • 自定义TabLayoutMediator,设置customView,放入自己的TextView
  • 内部自动添加一个addOnTabSelectedListener,在选中后使用动画渐进式的改变字体大小,同理取消选中时还原

解决过的坑:

  • TextView的文本在Size改变时,宽度动态变化,调用requestLayout()。Tab栏会因此触发重新测量与重绘,出现短促闪烁。塞两个TextView,一个作为最大边界并且设置INVISIBLE
  • 同样是重测问题,导致TabLayout额外多从头绘制一次Indicator时,直观表现就是每次切换Indicator时,会出现闪现消失。采用自定义了一个ScaleTexViewTabView,动态控制是否触发super.requestLayout

(因为已经准备了两个View,负责展示效果的View最大范围是明确无法超过既定范围的,所以这个办法不算“黑”)

  • 核心API:


fun <T : View> TabLayout.createMediatorByCustomTabView(
    vp: ViewPager2,
    config: CustomTabViewConfig<T>
): TabLayoutMediator {
    return TabLayoutMediator(this, vp) { tab, pos ->
        val tabView = config.getCustomView(tab.view.context)
        tab.customView = tabView
        config.onTabInit(tabView, pos)
    }
}

fun TabLayout.createTextScaleMediatorByTextView(
    vp: ViewPager2,
    config: TextScaleTabViewConfig
): TabLayoutMediator {

val mediator = createMediatorByCustomTabView(vp, config)
...
...
return mediator
}
  • 使用:

val mediator = tabLayout.createTextScaleMediatorByTextView(viewPager2,
    object : TextScaleTabViewConfig(scaleConfig) {
        override fun onBoundTextViewInit(boundSizeTextView: TextView, position: Int) {
            boundSizeTextView.textSizePx = scaleConfig.onSelectTextSize
            boundSizeTextView.text = tabs[position]
        }
        override fun onVisibleTextViewInit(dynamicSizeTextView: TextView, position: Int) {
            dynamicSizeTextView.setTextColor(Color.WHITE)
            dynamicSizeTextView.text = tabs[position]
        }
    })
mediator.attach()

整个代码去除通用拓展不过100行左右,不过鉴于其独立性还是要单独发布到基础组件库中。这样组件库中就有两个是单文件的组件了哈哈~ 

 需要文中源码的读者可以私信我

以上是关于ViewPager2&TabLayout:拓展出一个文本选中放大效果的主要内容,如果未能解决你的问题,请参考以下文章

由于 ViewPager2 导致 TabLayout 损坏

如何更新 Tablayout 中的片段? (Viewpager2, FragmentStateAdapter)

android使用Tablayout+viewpager2

TabLayout+ViewPager2的联合使用

在 TabLayout 和 ViewPager2 中执行异步任务后更新具有相同布局的多个片段

一起Talk Android吧(第三百七十七回:使用ViewPager2+TabLayout遇到的问题)