TabLayout的使用和自定义Tab样式

3,369 阅读1分钟

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字体样式,指定allCapstextStyle等
        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>

bcf9ca712d38ddc1d113630c02bf9158b2687ee3.png

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

bd49daa3234256e092c5477d31f31a13e62755fe.png