TabLayout : Set custom color for each tab
Asked Answered
P

5

6

I saw a lot of questions that say how to set the color differently for selected(active) and unselected(inactive) tabs. I also know that google provides void setTabTextColors (int normalColor, int selectedColor) to achieve this.

My requirement is a little different, I am working on a quiz app with a TabLayout and CardView. TabLayout allows the user to navigate between questions and CardView is used to display the questions.

I need to set the color of the tabs for which the user has already selected an answer differently than that for which the user has not answered yet. By default the TextColor is black but if the user selects an answer then the tabcolor should change to blue (just for eg.) and it should remain that way till the user exits. I have a int array called Select that will hold the value of the option that the user has selected (The values range between 1 - 4). While allocating the Select array I also initialize it with -1. I thought of setting up a loop and then if the array is -1 leave the tab as it is or set the tabcolor to blue.

How can I achieve this functionality?

Preliminary answered 7/12, 2016 at 15:46 Comment(0)
C
3

You can work with TabLayout internals by querying for this children and changing TextViews manually. This can break your code when you upgrade to another support library version, but as long as you keep track and test when updating, it should work:

private void updateTabTextColors() {
    LinearLayout tabsContainer = (LinearLayout) mTabLayout.getChildAt(0);
    for (int i = 0; i < mTabLayout.getTabCount(); i++) {
        LinearLayout item = (LinearLayout) tabsContainer.getChildAt(i);
        TextView tv = (TextView) item.getChildAt(1);
        tv.setTextColor(Select[i] == -1 ? Color.BLACK : Color.BLUE);
    }
}
Chloroprene answered 7/12, 2016 at 16:59 Comment(3)
github.com/RajNirmal/PreExam2.0/blob/master/app/src/main/java/…Preliminary
I tried the code but it is throwing NullPointerException at TextView tv = (TextView) item.getChildAt(1); Before that it worked but if I select the answer for the first question the second question's color changed. Please refer to the code in the GitHub pagePreliminary
Solved it. A problem with my previous code.. Now working as it should be.Preliminary
B
2

Just enhancing Marcelo Liberato's answer to support custom background for each tab item.

    LinearLayout tabsContainer = (LinearLayout) mTabLayout.getChildAt(0);
    LinearLayout childLayout1 = (LinearLayout)tabsContainer.getChildAt(2);
    LinearLayout childLayout2 = (LinearLayout)tabsContainer.getChildAt(3);

    LinearLayout tabView = (LinearLayout) childLayout1.getChildAt(0).getParent();
    tabView.setBackgroundResource(R.drawable.ic_blue_selector);

    tabView = (LinearLayout) childLayout2.getChildAt(0).getParent();
    tabView.setBackgroundResource(R.drawable.ic_red_selector);

Custom xml file:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/ll_tab_holder"
    android:orientation="vertical">

    <LinearLayout
        android:id="@+id/ll_tab_icon_title_holder"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/tab_icon"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:scaleType="fitCenter" />

        <TextView
            android:id="@+id/tab_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:textAppearance="@style/lasuCustomTabText" />
    </LinearLayout>

    <TextView
        android:id="@+id/tab_only_title"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:textAllCaps="true"
        android:textSize="12sp"
        android:layout_gravity="center"
        android:gravity="center"
        android:textColor="@drawable/ic_tab_text_color_selector" />
</LinearLayout>

Output: enter image description here

Bevan answered 23/8, 2017 at 2:29 Comment(0)
D
0

If you are interested in using a library for this functionality, this library works well.

https://github.com/astuetz/PagerSlidingTabStrip

enter image description here

Dielectric answered 7/12, 2016 at 16:9 Comment(2)
I would like to try this but I already have 100+ lines of code based on Tablayout. I don't how this library is going to affect thatPreliminary
Also I am using CardView not ViewPager as it is in the libraryPreliminary
L
0

As in the doc getTabTextColors() -> Gets the text colors for the different states (normal, selected) used for the tabs. the tabs can only have 2 states. The only way to achieve what you want if to inherit Tab class and add a new state, something like: tabAlreadyVisited. Then @Override the draw method to change background color based on the tabAlreadyVisited attribute value. Or change the text color with setTabTextColors

Lucchesi answered 7/12, 2016 at 16:45 Comment(0)
M
0

It's possible to set custom view for your tab

 TabLayout.Tab yourTab = tabLayout.newTab();
 yourTab.setCustomView(R.layout.red_text_view);

And red_text_view.xml is

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
      android:id="@android:id/text1"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:fontFamily="sans-serif-medium"
      android:gravity="center"
      android:textColor="#f44336"/>

If you use the @android:id/text1 default Tab's settext should work. You could do whatever you want with your custom view.

Melanite answered 4/10, 2018 at 18:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.