Bootstrap

Android TabLayout 选中 tab 文字加粗显示

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

示例功能说明

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

定义页面

首先需要在 下的 中添加如下依赖:

implementation 'com.google.android.material:material:1.3.0-alpha04'

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

implementation 'com.android.support:design:28.0.0'

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




    

        

        

        

        

        
    

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

分析问题

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

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

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

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

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

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

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

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

选中tab文字加粗

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

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不是加粗的,那么我们就在 方法中调用这个方法即可:

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);
}

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

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定义的 :



    
    

小结

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

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