When you use vector drawables as icons you might want to reuse a single drawables for different states, by simply tinting it differently. This way you can reduce the apk size and the allocation of resources. First define a custom FragmentPagerAdapter (I am using kotlin instead of java here)
class TabPagerAdapter(fm: FragmentManager) : FragmentPagerAdapter(fm) {
override fun getCount(): Int = 2
override fun getItem(position: Int): Fragment = when (position) {
0 -> FirstFragment.newInstance()
else -> SecondFragment.newInstance()
}
fun getPageIcon(context: Context, position: Int): Drawable = when (position) {
0 -> ContextCompat.getDrawable(context, R.drawable.ic_whatshot)
else -> ContextCompat.getDrawable(context, R.drawable.ic_face)
}
}
Instead of implementing getPageTitle
we create a getPageIcon
method, that returns a drawable for a specific tab. Next we create a custom TabLayout:
class IconTabLayout : TabLayout {
private var viewPager: ViewPager? = null
constructor(context: Context) : super(context)
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr)
override fun onAttachedToWindow() {
if (viewPager == null) {
if (parent is ViewPager) viewPager = parent as ViewPager
}
super.onAttachedToWindow()
}
override fun setupWithViewPager(viewPager: ViewPager?, autoRefresh: Boolean) {
this.viewPager = viewPager
super.setupWithViewPager(viewPager, autoRefresh)
}
override fun addTab(@NonNull tab: Tab, position: Int, setSelected: Boolean) {
if (viewPager != null && viewPager!!.adapter is TabPagerAdapter) {
val icon: Drawable = DrawableCompat.wrap((viewPager!!.adapter as TabPagerAdapter).getPageIcon(context, position))
DrawableCompat.setTintList(icon.mutate(), ContextCompat.getColorStateList(context, R.color.tab_color))
tab.icon = icon
}
super.addTab(tab, position, setSelected)
}
}
So the magic happens in the addTab
method, where the icon and the color state list are set. The color state list has following structure:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Non focused states -->
<item android:color="@color/tab_not_active" android:state_focused="false" android:state_pressed="false" android:state_selected="false" />
<item android:color="@color/tab_active" android:state_focused="false" android:state_pressed="false" android:state_selected="true" />
<!-- Focused states -->
<item android:color="@color/tab_not_active" android:state_focused="true" android:state_pressed="false" android:state_selected="false" />
<item android:color="@color/tab_active" android:state_focused="true" android:state_pressed="false" android:state_selected="true" />
<!-- Pressed -->
<item android:color="@color/tab_not_active" android:state_pressed="true" />
</selector>