Android TabLayout选中TabItem的背景自定义实现方案
实现自定义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
相关产品推荐
相关产品推荐

