ViewPager2 已发布过一段时间,已经步入正式版本,今天我们就来聊聊ViewPager的一些简单用法,以及与TabLayout的搭配使用。话不多说,进入正题。
首先我们来看一下,本次教程的最终效果。如图。
首先要想要使用ViewPager2 ,需要手动添加如下依赖至项目的gradle文件下。
dependencies {
implementation "androidx.viewpager2:viewpager2:1.0.0"
}
依赖添加完毕之后,就可以在布局文件中使用。举个栗子:
TabLayout 属性介绍
app:tabIndicatorColor
tab指示器的颜色
app:tabIndicator
自定义tab指示器的背景颜色,要想生效,需将app:tabIndicatorColor
属性设为null
app:tabIndicatorFullWidth
tab 指示器是否充满屏幕,默认为true
app:tabMode
tab 显示模式,有三种模式,fixed
、auto
、scrollable
app:tabTextColor
tab指示器未选中时文字颜色
app:tabSelectedTextColor
tab指示器选中时文字颜色
app:tabTextAppearance
tab指示器文字自定义属性,比如文字大小,字体粗细等
app:tabUnboundedRipple
tab指示器按钮按下反馈效果
让我们分别看看app:tabIndicator
以及app:tabTextAppearance
属性如何赋值。
1、app:tabIndicator
2、app:tabTextAppearance
ViewPager2与TabLayout关联
ViewPager2与TabLayout不同于ViewPager,此处需使用TabLayoutMediator。举个栗子。
private lateinit var binding: ActivityMainBinding
private lateinit var adapter: ViewPagerFragmentStateAdapter
private val tabTileList = arrayOf("春天", "夏天的风")
// 将tabLayout 与 viewPager绑定
TabLayoutMediator(binding.tlTab, binding.vpContainer) { tab, position ->
tab.text = tabTileList[position]
}.attach()
ViewPager2 适配器介绍
ViewPager2 中建议使用FragmentStateAdapter。
class ViewPagerFragmentStateAdapter(
fragmentManager: FragmentManager,
lifecycle: Lifecycle
) :
FragmentStateAdapter(fragmentManager, lifecycle) {
private var mDataList = mutableListOf()
override fun createFragment(position: Int): Fragment {
return mDataList[position]
}
override fun getItemCount(): Int {
return mDataList.size
}
fun addFragment(fragmennt: Fragment) {
mDataList.add(fragmennt)
}
}
ViewPager2 滑动水波纹去除
ViewPager不可使用android:overScrollMode="never"
属性去除水波纹,因为其滑动实现是通过内部RecycleView 实现。我们需要做的是设置其内部recyleview 滑动模式。
try {
val field = binding.vpContainer.javaClass.getDeclaredField("mRecyclerView")
field.isAccessible = true
val recycleView = field.get(binding.vpContainer) as RecyclerView
recycleView.overScrollMode = View.OVER_SCROLL_NEVER
} catch (ex: Exception) {
Log.d(TAG, "$ex")
}
TabLayout Tab选中时文字需加粗
通过源码,了解到其内部封装了TextView,通过app:tabTextAppearance
属性设置的文字属性,tab选中和未选中样式一致,乏善可陈。所以另辟蹊径,通过SpannableString来达到目的。举个栗子。
// 设置选中tab标题加粗
binding.tlTab.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab?) {
tab?.apply {
val selectTab = text.toString().trim()
val spannedString = SpannableString(selectTab)
val styleSpan = StyleSpan(Typeface.NORMAL)
spannedString.setSpan(
styleSpan,
0,
selectTab.length,
Spanned.SPAN_INCLUSIVE_INCLUSIVE
)
tab.text = spannedString
}
}
override fun onTabUnselected(tab: TabLayout.Tab?) {
tab?.apply {
val unselectTab = text.toString().trim()
val spannedString = SpannableString(unselectTab)
val styleSpan = StyleSpan(Typeface.NORMAL)
spannedString.setSpan(
styleSpan,
0,
unselectTab.length,
Spanned.SPAN_INCLUSIVE_INCLUSIVE
)
tab.text = spannedString
}
}
override fun onTabReselected(tab: TabLayout.Tab?) {
// do nothing
}
})
val selectTab = tabTileList[0]
val spannedString = SpannableString(selectTab)
val styleSpan = StyleSpan(Typeface.NORMAL)
spannedString.setSpan(
styleSpan,
0,
selectTab.length,
Spanned.SPAN_INCLUSIVE_INCLUSIVE
)
binding.tlTab.getTabAt(0)?.text = spannedString
写在最后
ViewPager2 较ViewPage做了很多优化,例如支持上下滑动,缓存优化等。ViewPager2有着更多的用法值得我们去探究。入股不亏。如果喜欢,给点喜欢。