ViewPager2正式推出已經一年多了,雖然不如3那樣新潮,但是也不如老前輩ViewPager那樣有眾多開源庫擁簇,比如它的靈魂伴侶TabLayout明顯后援不足,好在TabLayout自身夠硬!
ViewPager2靈魂伴侶是官方提供的:
com.google.android.material.tabs.TabLayout
TabLayout 利用其良好的設計,使得自定義非常容易,
像匹配ViewPager的優秀開源庫FlycoTabLayout的效果,使用TabLayout都能比較容易的實作:
FlycoTabLayout 演示

實作上圖中的幾個常用效果TabLayout 僅需在xml重配置即可
不過稍微不同的是,上圖中第二第三欄選中后的字體是有放大效果的,
這是利用TabLayout.Tab的customView屬性達到的,下文便是實作的思路與程序記錄,
正文
思路拆解:
- 介于此功能耦合點僅僅是
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行左右,不過鑒于其獨立性還是要單獨發布到基礎組件庫中,這樣組件庫中就有兩個是單檔案的組件了哈哈~
需要文中原始碼的讀者可以私信我
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/302267.html
標籤:其他
