写点什么

Android TabLayout 选中 tab 文字加粗显示

作者:逆锋起笔
  • 2022 年 3 月 08 日
  • 本文字数:3073 字

    阅读完需:约 10 分钟

Android TabLayout 选中 tab 文字加粗显示

TabLayout 是谷歌官方推出的一款横向标签可滑动选择的控件,非常实用,几乎主流 APP 里面都能看到类似这样的功能,尤其是资讯类和视频类,随着官方的更新,这款控件也越来越好用了,支持的属性基本能满足日常需求。下面就记录一下扩展实现的一个功能和几个属性的小技巧。

示例功能说明

只有一个页面,页面中只有TabLayout ,TabLayout 的子itemxml 中添加,使用官方控件com.google.android.material.tabs.TabItem,我们的目的是要实现当 tab 切换时,对应选中的 tab 文字加粗,反之正常。

定义页面

首先需要在 app 下的 build.gradle 中添加如下依赖:


implementation 'com.google.android.material:material:1.3.0-alpha04'
复制代码


这个引用是因为我的项目依赖库是基于 AndroidX 的,如果你是 support的,那么添加如下依赖:


implementation 'com.android.support:design:28.0.0'
复制代码


接下来就可以写布局文件了,Activity 对应xml代码如下:


<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">
<com.google.android.material.tabs.TabLayout android:id="@+id/tab_layout" android:layout_width="match_parent" android:layout_height="48dp" android:overScrollMode="never" app:tabMode="scrollable" app:tabSelectedTextColor="@android:color/holo_red_light">
<com.google.android.material.tabs.TabItem android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Java" />
<com.google.android.material.tabs.TabItem android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Android" />
<com.google.android.material.tabs.TabItem android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="vue" />
<com.google.android.material.tabs.TabItem android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="flutter" />
<com.google.android.material.tabs.TabItem android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Kotlin" /> </com.google.android.material.tabs.TabLayout></LinearLayout>
复制代码


这里为了简单,就不与 ViewPager 结合演示了,其实并不影响,我们的重点工作是在 TabLayout 中。运行起来,如下图:



分析问题

很明显,我们看到这里具体满足我们的需求差了很大一截,有几个问题:


  • tab 中的文字英文字母都大写了

  • tab 对应的指示器线宽度不跟随文字长度

  • 切换的时候并不会加粗当前选中的 tab


对于前两个问题解决起来并不难,通过TabLayout 属性就可以解决:


// 设置指示器线宽度跟随tab文字长度app:tabIndicatorFullWidth="false"// 避免默认英文字母大写app:tabTextAppearance="@android:style/TextAppearance.Widget.TabWidget"
复制代码


这样设置,前两个问题就解决了,看下图:



现在剩下最后一个问题了,也是本文的重点,需要我们在代码中实现。

选中 tab 文字加粗

这个其实一开始我的思路走错了,因为我的 tab 不是自定义的布局,而是通过接口获取数据动态显示的,并实现了与 ViewPager 的联动,初步想法是通过自定义 Tab 选中与否的样式来控制,实际操作发现不可行,最后看到一位博主提供的思路比较巧妙,是通过监听切换给 tab 设置 StyleSpan 来实现的,示例代码如下:


tabLayoutBinding.tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override public void onTabSelected(TabLayout.Tab tab) { if (tab == null || tab.getText() == null) { return; }
String selectTab = tab.getText().toString().trim();
SpannableString spannableString = new SpannableString(selectTab); StyleSpan styleSpan = new StyleSpan(Typeface.BOLD); spannableString.setSpan(styleSpan, 0, selectTab.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
tab.setText(spannableString); }
@Override public void onTabUnselected(TabLayout.Tab tab) { if (tab == null || tab.getText() == null) {
return; }
String selectTab = tab.getText().toString().trim();
SpannableString spannableString = new SpannableString(selectTab); StyleSpan styleSpan = new StyleSpan(Typeface.NORMAL); spannableString.setSpan(styleSpan, 0, selectTab.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
tab.setText(spannableString); }
@Override public void onTabReselected(TabLayout.Tab tab) { }});
复制代码


这样设置后,我们再看下效果:



当我们切换 tab 时,选中的 tab 文字就会加粗显示,但有一个问题,初次打开,默认选中的第一个 tab 不是加粗的,那么我们就在 onCreate() 方法中调用这个方法即可:


private void initFirstTab() {    TabLayout.Tab tab = tabLayoutBinding.tabLayout.getTabAt(0);    String selectTab = tab.getText().toString().trim();
SpannableString spannableString = new SpannableString(selectTab); StyleSpan styleSpan = new StyleSpan(Typeface.BOLD); spannableString.setSpan(styleSpan, 0, selectTab.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
tab.setText(spannableString);}
复制代码


实际开发中请不要在这里直接调用,一定要确保你的tab item 数据是有的,之后再调用,避免空指针。

TabLayout 几个常用属性

  • tabRippleColor:默认会有一个选中的水波纹效果,如果不想要,将其设置为透明即可

  • tabIndicatorHeight:指示器线条的高度,如果不想要,设置为 0 即可


关于指示器的状态颜色,这里不做解释,自定义想要的 xml 即可。

给 TabLayout item 设置分割线

一般情况是不会有分割线的,但有些需求甚是奇怪,每个 tab 之间会有一个竖向的短线,大家应该能理解,实现起来也不难,看代码:


LinearLayout linearLayout = (LinearLayout) tabLayout.getChildAt(0);linearLayout.setDividerPadding(30);linearLayout.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);linearLayout.setDividerDrawable(ContextCompat.getDrawable(this,R.drawable.layout_divider_vertical));
复制代码


其中的线条就是 xml 定义的 layout_divider_vertical.xml


<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android">    <solid android:color="#ff0000"/>    <size android:width="1dp"/></shape>
复制代码

小结

本文介绍的常用属性和解决方案,其实很多时候会遇到,但总会忘记,这里记录一下,以方便后续开发,提高效率。


我是一名安卓开发工程师,最近正在学习 Java 后端知识,每天保持学习,掌握一项技能其实用不了多长时间,加油!

发布于: 刚刚阅读数: 2
用户头像

逆锋起笔

关注

公众号「逆锋起笔」主理人 2018.07.31 加入

程序视角,转射人生!

评论

发布
暂无评论
Android TabLayout 选中 tab 文字加粗显示_android_逆锋起笔_InfoQ写作平台