最近在做项目的时候,遇到了TabLayout + ViewPager2 + Fragment的技术实现。一般TabLayout自带的默认字体并不能满足设计老师的需求。尽管有 app:tabTextAppearance 这个属性可以自定义默认的大小,但往往也是无法达到预期的效果。因此我们需要对TabLayout的Tab进行一个自定义的样式,具体的方式网上很多都可以查到,核心做法就是用自定义的View赋值给TabLayout的customView。具体代码如下:
list?.forEach { data ->
val tab = tabLayout.newTab().setText(data.data.name)
val view =
LayoutInflater.from(requireContext())
.inflate(R.layout.grade_tabs_item_view, null)
val text = view.findViewById<TextView>(R.id.grade_tab_item_text)
text.text = tab.text
tab.customView = view
tabLayout.addTab(tab)
}
这样就可以将TabLayout默认样式换成我们自己的样式,不过往往选中的样式和未选中的样式有所差别,因此我们需要监听一下TabLayout的Tab选中事件并做出样式改变,如下:
tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab?) {
tab?.apply {
updateTabItemView(tab, true)
viewModel.dealSelectCategory(this.position)
}
}
override fun onTabUnselected(tab: TabLayout.Tab?) {
tab?.apply {
updateTabItemView(tab, false)
}
}
override fun onTabReselected(tab: TabLayout.Tab?) {
}
})
private fun updateTabItemView(tab: TabLayout.Tab, isSelect: Boolean) {
tab.customView?.apply {
val text = findViewById<TextView>(R.id.grade_tab_item_text)
if (isSelect) {
text.background =
ContextCompat.getDrawable(
context,
R.drawable.custom_content_selected_background
)
text.setTextColor(ContextCompat.getColor(context, R.color.white))
} else {
text.setTextColor(ContextCompat.getColor(context, R.color.tab_select_color))
text.background = ContextCompat.getDrawable(
context,
R.drawable.custom_content_selector_background
)
}
}
}
如果只是对TabLayout进行自定义样式的话,到这里其实已经结束了,可以添加自己的后续逻辑,但是可惜,当使用TabLayoutMediator进行TabLayout和ViewPager2的连接的时候,我们自定义Tab的样式会失效,重新回归到一个默认的情况,原因在于在TabLayoutMediator进行两者关联的时候会将自定义的样式清除掉,因此在与ViewPager2进行搭配使用的时候,不能采用上述的方式进行操作。正确的做法应该是在TabLayoutMediator进行连接的时候进行自定义样式。具体做法如下:
TabLayoutMediator(
tablayout,
hpPaperViewpager2,
false,
false
) { tab, position ->
val view = LayoutInflater.from(this@HomePageActivity)
.inflate(R.layout.subject_tab_item, null)
tab.customView = view
val tabTextView =
tab.customView!!.findViewById<TextView>(R.id.subject_tab_item_name)
tabTextView.text = it[position].name
}.attach()
选中监听时候的做法不变。