【问题标题】:TabLayout : Set custom color for each tabTabLayout : 为每个选项卡设置自定义颜色
【发布时间】:2019-06-27 15:45:30
【问题描述】:

我看到很多问题都说如何为选定(活动)和未选定(非活动)选项卡设置不同的颜色。我也知道谷歌提供void setTabTextColors (int normalColor, int selectedColor) 来实现这一点。

我的要求有点不同,我正在开发一个带有TabLayoutCardView 的测验应用程序。 TabLayout 允许用户在问题之间导航,CardView 用于显示问题。

我需要将用户已选择答案的选项卡的颜色设置为与用户尚未回答的选项卡颜色不同。默认情况下,TextColor 为黑色,但如果用户选择答案,则 tabcolor 应更改为蓝色(仅用于例如),并且应保持这种状态,直到用户退出。我有一个名为Selectint 数组,它将保存用户选择的选项的值(值范围在1-4 之间)。在分配Select 数组时,我还将它初始化为-1。我想设置一个循环,然后如果数组是-1,则保留选项卡原样或将选项卡颜色设置为蓝色。

我怎样才能实现这个功能?

【问题讨论】:

    标签: android android-tablayout


    【解决方案1】:

    您可以通过查询此子项并手动更改 TextViews 来使用 TabLayout 内部。当您升级到另一个支持库版本时,这可能会破坏您的代码,但只要您在更新时跟踪和测试,它应该可以工作:

    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);
        }
    }
    

    【讨论】:

    • 我尝试了代码,但它在TextView tv = (TextView) item.getChildAt(1); 抛出 NullPointerException 之前它有效,但如果我选择第一个问题的答案,第二个问题的颜色会改变。请参考GitHub页面中的代码
    • 解决了。我以前的代码有问题。现在可以正常工作了。
    【解决方案2】:

    只是增强Marcelo Liberato 的答案以支持每个选项卡项的自定义背景。

        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);
    

    自定义xml文件:

    <?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>
    

    输出:

    【讨论】:

      【解决方案3】:

      如果您有兴趣使用某个库来实现此功能,那么这个库可以很好地工作。

      https://github.com/astuetz/PagerSlidingTabStrip

      【讨论】:

      • 我想试试这个,但我已经有 100 多行基于 Tablayout 的代码。我不知道这个图书馆会如何影响这一点
      • 我也使用CardView 而不是ViewPager,因为它在库中
      【解决方案4】:

      doc getTabTextColors() -&gt; Gets the text colors for the different states (normal, selected) used for the tabs. 一样,选项卡只能有两种状态。如果继承Tab 类并添加新状态,则实现您想要的唯一方法,例如:tabAlreadyVisited。然后@Overridedraw方法根据tabAlreadyVisited属性值改变背景颜色。或者用setTabTextColors改变文字颜色

      【讨论】:

        【解决方案5】:

        可以为您的标签设置自定义视图

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

        red_text_view.xml

        <?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"/>
        

        如果您使用@android:id/text1 默认选项卡的 settext 应该可以工作。您可以使用自定义视图做任何您想做的事情。

        【讨论】: