当使用TabLayout时,我如何更改选项卡的背景颜色?

144

这是我在主活动中的代码

public class FilterActivity extends AppCompatActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_filter);

    // Get the ViewPager and set it's PagerAdapter so that it can display items
    ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
    PageAdapter pageAdapter = new PageAdapter(getSupportFragmentManager(), FilterActivity.this);
    viewPager.setAdapter(pageAdapter);

    // Give the TabLayout the ViewPager
    final TabLayout tabLayout = (TabLayout) findViewById(R.id.sliding_tabs);
    tabLayout.setupWithViewPager(viewPager);



  }
}

这是我的XML代码

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <include
        android:id="@+id/app_bar"
        layout="@layout/app_bar">
    </include>

    <android.support.design.widget.TabLayout
        android:id="@+id/sliding_tabs"
        android:layout_width="fill_parent"
        style="@style/MyCustomTabLayout"
        android:layout_height="48dp"/>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="0px"
        android:layout_weight="1"
        android:background="@android:color/white" />

</LinearLayout>

当选中一个选项卡时,我想要改变它的背景颜色。

14个回答

338

最后对我有用的方法与@如果我是DJ建议的类似,但tabBackground应该在layout文件中而不是style中,因此看起来像:

res/layout/somefile.xml:

<android.support.design.widget.TabLayout
    ....
    app:tabBackground="@drawable/tab_color_selector"
    ...
    />

选择器的位置是res/drawable/tab_color_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/tab_background_selected" android:state_selected="true"/>
    <item android:drawable="@color/tab_background_unselected"/>
</selector>

2
您还可以将颜色值添加到该属性中:即:app:tabBackground:@color/colorAccent - Val Martinez
谢谢你的解决方案。然而,我失去了默认的涟漪效果。 - Ken Ratanachai S.
4
我可以为您进行编程方面的翻译。要让内容更加通俗易懂,但不改变原意。以下是需要翻译的内容:"How can I do this programatically?" - TSR
1
@TSR,如果您不需要为每个选项卡使用不同的颜色,则可以使用tabLayout.setBackgroundColor(colorInt)。如果您需要为每个选项卡设置不同的颜色,则可以从TabLayout中提取其子项。 - karl
1
为了改善外观和感觉,我认为我们还应该添加state_pressed: **<item android:drawable="@color/tab_background_selected" android:state_pressed="true"/>**。 - Phong Nguyen
显示剩余3条评论

21

你可以尝试这个:

<style name="MyCustomTabLayout" parent="Widget.Design.TabLayout">
    <item name="tabBackground">@drawable/background</item>
</style>
在您的背景XML文件中:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true" android:drawable="@color/white" />
    <item android:drawable="@color/black" />
</selector>

如何实现这个? - TSR
在XML中为您的TabLayout添加属性android:style。 - amtrax

15
在XML中添加属性:
<android.support.design.widget.TabLayout
    ....
    app:tabBackground="@drawable/tab_color_selector"
    ...
    />

在drawable文件夹中创建tab_color_selector.xml文件

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/tab_background_selected" android:state_selected="true"/>
    <item android:drawable="@color/tab_background_unselected"/>
</selector>

14

我找到的一种方法是使用标签指示器,像这样:

<com.google.android.material.tabs.TabLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:tabBackground="@color/normal_unselected_color"
    app:tabIndicatorColor="@color/selected_color"
    app:tabIndicatorGravity="center"
    app:tabIndicatorHeight="150dp"
    app:tabSelectedTextColor="@color/selected_text_color"
    app:tabTextColor="@color/unselected_text_color">

    ..... tab items here .....

</com.google.android.material.tabs.TabLayout>

技巧在于:

  • 使选项卡指示器居中对齐
  • 将指示器高度设置足够大,以便覆盖整个选项卡

这也可以确保在切换选项卡时平滑动画的呈现。


7
您可以在xml中使用它。
<android.support.design.widget.TabLayout
        android:id="@+id/tabs"
        app:tabTextColor="@color/colorGray"
        app:tabSelectedTextColor="@color/colorWhite"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

6
在一些尝试后,这是我得到期望外观的方法(至少在模拟器中),并且它保留了涟漪效果。

tab layout with tab selector with color argument

<com.google.android.material.tabs.TabLayout
    android:id="@+id/tabs"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:tabBackground="@drawable/tab_selector"
    app:tabIconTint="@drawable/tab_selector"
    app:tabIconTintMode="src_atop"
    app:tabTextColor="@drawable/tab_selector" />

还有@drawable/tab_selector

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/colorPrimary" android:drawable="@color/colorPrimaryDark" android:state_selected="true" />
    <item android:color="@color/colorPrimaryDark" android:drawable="@color/colorPrimary" />
</selector>

提示:在我向@drawable/tab_selector添加color参数之前,模拟器显示的是这样的:

tab layout with tab selector without color argument


5
您尝试过查看 API 吗?
您需要为 OnTabSelectedListener 事件创建监听器,然后当用户选择任何选项卡时,应检查是否为正确选项卡,使用 tabLayout.setBackgroundColor(int color) 更改背景颜色,或者如果不是正确选项卡,请使用相同的方法确保将其更改回正常颜色。

是的,我已经尝试过了,但是tabLayout会改变整个选项卡小部件的颜色,而且我找不到一个只改变选项卡颜色而其他选项卡保持相同颜色的tabLayout.Tab方法。 - Joel Lara
我不是100%确定你想要什么。如果你只想给一个选项卡的主体上色,那么你可以在该选项卡内添加一个容器/视图,然后你应该能够像平常一样在XML中设置容器/视图的背景颜色,例如以下代码将把背景设置为红色 android:background=FF0000 - sorifiend
这些其他的问题/答案可能会对您有所帮助:https://dev59.com/PV0Z5IYBdhLWcg3w6j-_ 和 https://dev59.com/UV0a5IYBdhLWcg3wD1Hb#30755351 - sorifiend

2

我找到了最适合我的选项,而且它还可以与动画一起使用。

您可以将indicator本身用作背景。

您可以设置app:tabIndicatorGravity="stretch"属性作为背景使用。

示例:

   <android.support.design.widget.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabIndicatorGravity="stretch"
        app:tabSelectedTextColor="@color/white"
        app:tabTextColor="@color/colorAccent">

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


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

    </android.support.design.widget.TabLayout>

希望这能帮到你。


这是自动获取强调颜色。如何在不改变强调颜色的情况下给它不同的颜色。谢谢。 - MindRoasterMir
2
你可以使用 app:tabIndicatorColor @MindRoasterMir - Pratik Butani

2

由于ViewPager正在被ViewPager2取代,我们需要进行迁移。

使用Java的一个快速解决方法可能是这样的:

    final List<String> colors = new ArrayList<String>(){
        {
            add("#FF0000");
            add("#800000");
            add("#FFFF00");
        }
    };

    
    ViewPager2 viewPager = findViewById(R.id.viewPager);
    ViewPagerAdapter adapter = new ViewPagerAdapter(your_data_structure);
    viewPager.setAdapter(adapter);

    final TabLayout tabs = findViewById(R.id.tabs);

    tabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            tab.view.setAlpha((float) 0.5);
        }

        @Override
        public void onTabUnselected(TabLayout.Tab tab) {
            tab.view.setAlpha(1);
        }

        @Override
        public void onTabReselected(TabLayout.Tab tab) {

        }
    });

    TabLayoutMediator mediator = new TabLayoutMediator(tabs, viewPager, new TabLayoutMediator.TabConfigurationStrategy() {
        @Override
        public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
            tab.setText("Tab" + position);
            
            /* 
            *  With this feature the TabIndicator color is ignored 
            *  or covered by the new color ex.(if alpha channel is changed the indicator can be seen through)
            */
            tab.view.setBackgroundColor(Color.parseColor(colors.get(position))); //You can use your HEX string color
        }
    });

    mediator.attach();

1
您可以像这样更改每个选项卡的背景或涟漪颜色:
    //set ripple color for each tab
    for(int n = 0; n < mTabLayout.getTabCount(); n++){

        View tab = ((ViewGroup)mTabLayout.getChildAt(0)).getChildAt(n);

        if(tab != null && tab.getBackground() instanceof RippleDrawable){
            RippleDrawable rippleDrawable = (RippleDrawable)tab.getBackground();
            if (rippleDrawable != null) {
                rippleDrawable.setColor(ColorStateList.valueOf(rippleColor));
            }
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接