1、使用:
导入material库:
implementation 'com.google.android.material:material:1.2.1' //导入库
布局文件: 用自定义drawable文件设置圆角指示器
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="0dp"
android:layout_height="44dp"
app:layout_constraintEnd_toStartOf="@id/ib_status"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tabMode="scrollable" //自适应宽度,宽度包裹内容
app:tabIndicator="@drawable/tab_indicator" //标签指示器样式,这里设置为圆角,长宽、边距等都可以设置
app:tabBackground="@color/tabBackground" //设置Tab背景
app:tabIndicatorFullWidth="false" //设置指示器不填充整个tab,即与字体内容同宽
app:tabIndicatorHeight="2dp" //指示器高度
app:tabIndicatorFullWidth="false" //指示器是否充满标签
app:tabPaddingEnd="@dimen/space_4"
app:tabPaddingStart="@dimen/space_4"
app:tabSelectedTextColor="@color/color_006157" //选中tab字体颜色
app:indicatorColor="@color/color_006157" //指示器颜色
app:tabTextAppearance="@style/MyTabText" //tab字体样式,指定allCaps,textStyle等
app:tabTextColor="@color/color_666666" //tab字体颜色
app:tabRippleColor="@color/colorTransparent" //标签按下时的反馈效果,这里设置透明色隐藏效果
/>
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:theme="@style/MyTablayout"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/tabLayout" />
自定义指示器tab_indicator,可以直接写一个shape。如果对指示器的尺寸、边距、位置有要求,可以将shape写在layer-list,在中对这些属性进行赋值:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke android:color="@color/colorAccent" />
<corners android:radius="3dp" />
<size android:height="3dp" />
</shape>
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:width="20dp" //长
android:height="2dp" //宽
android:bottom="4dp" //距底部距离
android:gravity="center_horizontal"> //设置width之后要设置为水平居中
<shape>
<solid android:color="@color/white" /> //颜色
</shape>
</item>
</layer-list>
指定字体样式tabLayoutTextStyle:
<style name="MyTabText" parent="@android:style/TextAppearance.Widget.TabWidget"> //该parent可以设置tab字体为非大写
<item name="android:textStyle">bold</item>
<item name="android:textSize">@dimen/font_14</item>
<item name="android:textColor">@color/color_464950</item>
</style>
无法直接设置tab间隔,只能通过自定义tabBackground样式,给背景设置左右间距来设置间隔:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:left="@dimen/space_4" //左右间距为4dp
android:right="@dimen/space_4">
<shape>
<stroke
android:width="@dimen/space_1"
android:color="@color/color_006157" />
<corners android:radius="@dimen/space_4" />
<solid android:color="@color/white" />
<padding
android:left="@dimen/space_4"
android:right="@dimen/space_4" />
</shape>
</item>
</layer-list>
//通过selector设置tab不同状态下的背景
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/bg_006157_stroke_1_corner_4" android:state_pressed="true" />
<item android:drawable="@drawable/bg_006157_stroke_1_corner_4" android:state_checked="true" />
<item android:drawable="@drawable/bg_006157_stroke_1_corner_4" android:state_selected="true" />
<item android:drawable="@drawable/bg_ffffff_corner_4" />
</selector>
与ViewPager一起使用:
private void initTitle() {
if (titles == null) { //tabLayout的字符串数组
titles = new String[]{getString(R.string.status_dialog_title), getString(R.string.splash_save_status)};
}
fragmentList = new ArrayList<Fragment>(); //Fragment列表
fragmentList.addAll(Arrays.asList(new AllStatusFragment(), new DownloadFragment()));
for (int i = 0; i < titles.length; i++) {
tabLayout.addTab(tabLayout.newTab()); //通过tabLayout.newTab()创建tab,添加到tabLayout
}
tabLayout.setupWithViewPager(viewPager, false); //tabLayout与ViewPager关联
FragmentPagerAdapter fm = new FragmentPagerAdapter(getChildFragmentManager()) { //getChildFragmentManager():fragment中嵌套fragment
//getActivity().getSupportFragmentManager():Activity中嵌套Fragment
@NonNull
@Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
@Override
public int getCount() {
return fragmentList.size();
}
};
viewPager.setAdapter(fm);
viewPager.setCurrentItem(0);
for (int i = 0; i < titles.length; i++) {
tabLayout.getTabAt(i).setText(titles[i]).setIcon(icons[i]); //设置tabLayout内容和icon
}
// 去掉点击的波纹效果
tabLayout.setTabRippleColor(ColorStateList.valueOf(getResources().getColor(R.color.transparent)));
//标签选中监听器
tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
override fun onTabReselected(tab: TabLayout.Tab?) {
}
override fun onTabUnselected(tab: TabLayout.Tab?) {
}
override fun onTabSelected(tab: TabLayout.Tab?) {
}
})
}
2、自定义tab样式
自定义tab布局:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="48dp">
<ImageView //需要在子组件中处理反馈色
android:id="@+id/tabicon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginTop="6dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/tabsign"
android:layout_width="18dp"
android:layout_height="18dp"
android:layout_gravity="right"
android:layout_marginStart="14dp"
android:src="@drawable/ic_sign"
android:visibility="gone"
app:layout_constraintStart_toStartOf="@id/tabicon"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tabtext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:layout_marginBottom="4dp"
android:textColor="@color/color_666666_to_3db446" //设置反馈色,tabSelectedTextColor无效
android:textSize="10sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
自定义的布局加载进来后通过TabLayout.Tab.setCustomView(View)设置进标签中:
private View getTabView(String title, int icon, boolean showSign) {
View v = LayoutInflater.from(this).inflate(R.layout.tab_item, null);
TextView tvTitle = v.findViewById(R.id.tabtext);
ImageView ivIcon = v.findViewById(R.id.tabicon);
tvTitle.setText(title);
ivIcon.setImageResource(icon);
if (showSign) {
v.findViewById(R.id.tabsign).setVisibility(View.VISIBLE);
}
return v;
}
for (int i = 0; i < tabs.length; i++) {
TabLayout.Tab tab = containerTab.getTabAt(i); //注意tab只能从现有的布局中的TabLayout获取,不能直接新建
boolean show = false;
if (i == 3) show = true;
tab.setCustomView(getTabView(tabs[i], icons[i], show)); //设置自定义的tabView
}
3、添加分割线 分隔线
//分割线布局
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:width="0.5dp"
android:height="12dp"
android:gravity="center">
<shape>
<solid android:color="@color/color_D8D8D8" />
</shape>
</item>
</layer-list>
//添加分隔线,tab就是tablayout
val linearLayout=tab.getChildAt(0) as LinearLayout
linearLayout.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);
linearLayout.setDividerDrawable(ContextCompat.getDrawable(requireContext(),R.drawable.shape_divide_recommend))