You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android TabLayout选中TabItem的背景自定义实现方案

实现自定义TabLayout样式

我想要实现这样的TabLayout设计:
预期设计

目前已完成的效果:
已实现的TabLayout

需要帮忙实现两个需求:

  • 选中Tab时,背景填充该Tab的左半部分或右半部分
  • 选中的TabItem背景需留有小边距,不能完全填满Tab

当前代码如下:

MainActivity.xml

<com.google.android.material.tabs.TabLayout
    android:id="@+id/tab"
    android:layout_width="440sp"
    android:layout_height="64sp"
    android:layout_marginTop="100dp"
    android:layout_marginBottom="101dp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    android:background="@drawable/backGroundWithWhiteBorder"
    style="@style/customTabLayout"
    app:tabBackground="@drawable/tab_color_selector" />

tab_color_selector.xml

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

backGroundWithWhiteBorder.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="376dp"
    android:height="64dp"
    android:viewportWidth="376"
    android:viewportHeight="64">
  <path
      android:strokeWidth="1"
      android:fillColor="#00000000"
      android:strokeColor="#fff"/>
</vector>

Style.xml

<style name="customTabLayout" parent="Widget.Design.TabLayout">
    <item name="tabTextAppearance">@style/TabText</item>
</style>
<style name="TabText" parent="@android:style/TextAppearance.Widget.TabWidget">
    <item name="android:textAllCaps">false</item>
    <item name="android:textSize">30sp</item>
    <item name="android:textAlignment">center</item>
</style>

解决方案

1. 实现选中Tab的半侧背景+边距效果

要实现需求,不能直接用纯色作为选中状态的drawable,需要创建带边距的形状drawable,并通过代码区分左右Tab的背景样式:

步骤1:创建左侧Tab选中背景

新建tab_selected_left.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="@color/tiffany_blue" />
    <!-- 匹配整体背景的左侧圆角 -->
    <corners android:topLeftRadius="8dp" android:bottomLeftRadius="8dp" />
    <!-- 上下右留边距,避免填满Tab -->
    <padding android:top="4dp" android:bottom="4dp" android:right="8dp" />
</shape>
步骤2:创建右侧Tab选中背景

新建tab_selected_right.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="@color/tiffany_blue" />
    <!-- 匹配整体背景的右侧圆角 -->
    <corners android:topRightRadius="8dp" android:bottomRightRadius="8dp" />
    <!-- 上下左留边距 -->
    <padding android:top="4dp" android:bottom="4dp" android:left="8dp" />
</shape>
步骤3:创建未选中状态背景

新建tab_unselected.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="@color/transparent" />
</shape>
步骤4:创建自定义Tab布局

新建tab_custom_view.xml,用来控制Tab的文字和背景边距:

<?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:gravity="center"
    android:textAppearance="@style/TabText" />
步骤5:代码中动态设置Tab背景

在Activity中给TabLayout绑定选中监听,切换不同背景:

TabLayout tabLayout = findViewById(R.id.tab);

// 初始化所有Tab的自定义View和背景
for (int i = 0; i < tabLayout.getTabCount(); i++) {
    TabLayout.Tab tab = tabLayout.getTabAt(i);
    if (tab != null) {
        tab.setCustomView(R.layout.tab_custom_view);
        // 默认选中第一个Tab的话,设置左侧背景
        if (i == 0 && tab.isSelected()) {
            tab.getCustomView().setBackgroundResource(R.drawable.tab_selected_left);
        } else {
            tab.getCustomView().setBackgroundResource(R.drawable.tab_unselected);
        }
    }
}

// 监听Tab选中事件
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
    @Override
    public void onTabSelected(TabLayout.Tab tab) {
        int position = tab.getPosition();
        // 根据位置设置对应半侧背景
        if (position == 0) {
            tab.getCustomView().setBackgroundResource(R.drawable.tab_selected_left);
        } else if (position == 1) {
            tab.getCustomView().setBackgroundResource(R.drawable.tab_selected_right);
        }
        // 重置其他Tab的背景
        for (int i = 0; i < tabLayout.getTabCount(); i++) {
            if (i != position) {
                TabLayout.Tab unselectedTab = tabLayout.getTabAt(i);
                if (unselectedTab != null) {
                    unselectedTab.getCustomView().setBackgroundResource(R.drawable.tab_unselected);
                }
            }
        }
    }

    @Override
    public void onTabUnselected(TabLayout.Tab tab) {
        tab.getCustomView().setBackgroundResource(R.drawable.tab_unselected);
    }

    @Override
    public void onTabReselected(TabLayout.Tab tab) {}
});
步骤6:更新TabLayout配置和整体背景

修改MainActivity.xml,移除app:tabBackground(改用自定义View控制背景):

<com.google.android.material.tabs.TabLayout
    android:id="@+id/tab"
    android:layout_width="440sp"
    android:layout_height="64sp"
    android:layout_marginTop="100dp"
    android:layout_marginBottom="101dp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    android:background="@drawable/backGroundWithWhiteBorder"
    style="@style/customTabLayout" />

更新backGroundWithWhiteBorder.xml,给整体背景添加圆角,和选中Tab的圆角匹配:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="376dp"
    android:height="64dp"
    android:viewportWidth="376"
    android:viewportHeight="64">
  <path
      android:strokeWidth="1"
      android:fillColor="#00000000"
      android:strokeColor="#fff"
      android:pathData="M8,0 L368,0 A8,8 0 0 1 376,8 L376,56 A8,8 0 0 1 368,64 L8,64 A8,8 0 0 1 0,56 L0,8 A8,8 0 0 1 8,0 Z"/>
</vector>

内容的提问来源于stack exchange,提问作者Dev_Cob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 13:05:18