TabLayout.setTabTextColors() not working when trying to change text color
Asked Answered
C

4

10

I have a working TabLayout, and I am trying to update the tab text color dynamically, when changing tabs. To do this, I call the setTabTextColors() method on my TabLayout as such:

tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
    @Override
    public void onTabSelected(TabLayout.Tab tab) {
        tabLayout.setTabTextColors(newColorStateList);
    }

    (...)
});

For some reason, the text color doesn't update. Does anyone know how to update the tab text color dynamically?

I am using the Design Support Library v22.2.0.

Coyne answered 10/7, 2015 at 14:47 Comment(0)
S
4

It's finally fixed in Design Support Library 22.2.1.

        tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
          @Override
          public void onTabSelected(TabLayout.Tab tab) {
            tabLayout.setTabTextColors(getResources().getColor(R.color.normal), getResources().getColor(R.color.selected));

            try {
                // FIXME: 20.7.2015 WORKAROUND: https://code.google.com/p/android/issues/detail?id=175182 change indicator color
                Field field = TabLayout.class.getDeclaredField("mTabStrip");
                field.setAccessible(true);
                Object value = field.get(tabLayout);

                Method method = value.getClass().getDeclaredMethod("setSelectedIndicatorColor", Integer.TYPE);
                method.setAccessible(true);
                method.invoke(value, getResources().getColor(R.color.selected));
            } catch (Exception e) {
                e.printStackTrace();
            }
          }

        ...
        }
Sarene answered 20/7, 2015 at 11:5 Comment(0)
W
8

TabLayout has a method like this -

setTabTextColors(int normalColor, int selectedColor)

Remember, that int is not color resource value but int parsed from hex

Ex:

tabLayout.setTabTextColors(Color.parseColor("#D3D3D3"),Color.parseColor("#2196f3"))
Wriggle answered 14/4, 2019 at 18:0 Comment(1)
"Remember, that int is not color resource value but int parsed from hex" this is really helpful, thank youMelodramatic
C
4

After a bit of investigation, it seems like the textviews inside the TabLayout just don't get their colors updated after their creation.

The solution I came up with was to go through the children views of the TabLayout and update their colors directly.

public static void setChildTextViewsColor(ViewGroup viewGroup, ColorStateList colorStateList) {
    for (int i = 0; i < viewGroup.getChildCount(); i++) {
        View child = viewGroup.getChildAt(i);

        if (child instanceof ViewGroup) {
            setChildTextViewsColor((ViewGroup) child, colorStateList);
        } else if (child instanceof TextView) {
            TextView textView = (TextView) child;
            textView.setTextColor(colorStateList);
        }
    }
}

Then, in the OnTabSelectedListener:

    tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            setChildTextViewsColor(tabLayout, newColorStateList);
        }

        (...)
    });
Coyne answered 10/7, 2015 at 14:54 Comment(0)
S
4

It's finally fixed in Design Support Library 22.2.1.

        tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
          @Override
          public void onTabSelected(TabLayout.Tab tab) {
            tabLayout.setTabTextColors(getResources().getColor(R.color.normal), getResources().getColor(R.color.selected));

            try {
                // FIXME: 20.7.2015 WORKAROUND: https://code.google.com/p/android/issues/detail?id=175182 change indicator color
                Field field = TabLayout.class.getDeclaredField("mTabStrip");
                field.setAccessible(true);
                Object value = field.get(tabLayout);

                Method method = value.getClass().getDeclaredMethod("setSelectedIndicatorColor", Integer.TYPE);
                method.setAccessible(true);
                method.invoke(value, getResources().getColor(R.color.selected));
            } catch (Exception e) {
                e.printStackTrace();
            }
          }

        ...
        }
Sarene answered 20/7, 2015 at 11:5 Comment(0)
C
0

Also, make sure that you don't use separate xml file to style tabs. Something like this, like I had (custom_tab.xml):

    TextView tabOne = (TextView) LayoutInflater.from(this).inflate(R.layout.custom_tab, null);
    tabOne.setText(R.string.tab_response);
    tabOne.setCompoundDrawablesWithIntrinsicBounds(0, R.drawable.tab_bar_icon_response, 0, 0);
    tabLayout.getTabAt(0).setCustomView(tabOne); 
Coachandfour answered 26/11, 2015 at 15:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.