Search code examples
androidandroid-layouttabsandroid-tablayout

TabLayout tab text color state list


I want my TabLayout tabs have three different text colors depending on tab state:

  1. default - red
  2. disabled - yellow
  3. selected - green

I'm adding my TabLayout:

<android.support.design.widget.TabLayout
                android:id="@+id/tlBetTypes"
                style="@style/BetTabLayoutStyle"
                android:layout_width="match_parent"
                android:layout_height="38dp">

                <android.support.design.widget.TabItem
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/single"/>

                <android.support.design.widget.TabItem
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/multi"/>

                <android.support.design.widget.TabItem
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="@string/system"/>
</android.support.design.widget.TabLayout>

then BetTabLayoutStyle:

<style name="BetTabLayoutStyle">
    <item name="tabIndicatorHeight">0dp</item>
    <item name="tabTextAppearance">@style/BetTabTexStyle</item>
    <item name="tabBackground">@drawable/background_tab_bet_type</item>
</style>

then BetTabTexStyle:

<style name="BetTabTexStyle">
    <item name="android:textSize">@dimen/text_size_12</item>
    <item name="android:textColor">@color/tab_test</item>
    <item name="android:fontFamily">@font/roboto_medium</item>
    <item name="textAllCaps">true</item>
</style>

then tab_test.xml:

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/red"/>
    <item android:color="@color/yellow" android:state_enabled="false"/>
    <item android:color="@color/green" android:state_selected="true"/>
</selector>

But it's not working.

I also tried to create a ColorStateList from code and set and set is using setTabTextColors.

Could you please explain me what I'm doing wrong?


Solution

  • Two steps to solve this:

    1. set ColorStateList from code because TabLayout resets text appearance in constructor if you inflate it in xml.

      private void setupTabsStyle() {
      int[][] states = new int[][]{
              new int[]{android.R.attr.state_selected},
              new int[]{android.R.attr.state_enabled},
              new int[]{-android.R.attr.state_enabled}
      };
      
      @ColorRes int[] colorRes = new int[]{
              R.color.orange_1,
              R.color.grey_16,
              R.color.grey
      };
      
      @ColorInt int[] colors = new int[colorRes.length];
      
      for (int i = 0; i < colorRes.length; i++) {
          colors[i] = ContextCompat.getColor(getContext(), colorRes[i]);
      }
      
      ColorStateList colorList = new ColorStateList(states, colors);
      mTabLayout.setTabTextColors(colorList);
      }
      
    2. Disable TextView inside the tab, not only the tab itself. In particular we need to disable/enable only the TextView inside the TabView to achieve text appearance effect, but I disable the ImageView as well.

      private void enableTab(int tabIndex, boolean doEnable) {
          LinearLayout tabStrip = ((LinearLayout) mTabLayout.getChildAt(0));
          LinearLayout tabView = (LinearLayout) tabStrip.getChildAt(tabIndex);
          tabView.setEnabled(doEnable);
          for (int i = 0; i < tabView.getChildCount(); i++) {
              View childAt = tabView.getChildAt(i);
              childAt.setEnabled(doEnable);
          }
      }