You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现这款自定义Android Tab Layout?技术求助

嘿,我之前也折腾过类似的Tab Layout!从你提供的截图来看,这应该是一个带有自定义选中态动画和样式差异化的Material Design风格Tab栏,我把亲测有效的实现步骤拆解给你:

自定义Tab Layout实现指南

1. 先搭基础布局

首先在XML里定义TabLayout(如果需要和ViewPager联动,记得加上ViewPager),先把基础样式配置好:

<com.google.android.material.tabs.TabLayout
    android:id="@+id/tabLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:tabIndicatorColor="#FF4081"
    app:tabIndicatorHeight="3dp"
    app:tabTextColor="#666666"
    app:tabSelectedTextColor="#FF4081"
    app:tabPaddingStart="16dp"
    app:tabPaddingEnd="16dp" />

2. 自定义单个Tab的布局

创建layout_tab_item.xml,用来控制Tab文字的大小、内边距,方便后续做选中态变化:

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/tabText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textSize="14sp"
    android:textColor="#666666"
    android:paddingVertical="12dp" />

3. 代码绑定Tab并设置选中逻辑

在Activity/Fragment里,给TabLayout添加Tab项,同时监听选中状态来切换文字样式:

val tabLayout = findViewById<TabLayout>(R.id.tabLayout)
val tabTitles = listOf("首页", "发现", "我的")

// 循环添加自定义Tab
tabTitles.forEach { title ->
    val tab = tabLayout.newTab()
    val tabView = LayoutInflater.from(this).inflate(R.layout.layout_tab_item, null)
    val tabText = tabView.findViewById<TextView>(R.id.tabText)
    tabText.text = title
    tab.customView = tabView
    tabLayout.addTab(tab)
}

// 监听Tab选中事件,切换文字大小和颜色
tabLayout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
    override fun onTabSelected(tab: TabLayout.Tab) {
        val tabText = tab.customView?.findViewById<TextView>(R.id.tabText)
        tabText?.apply {
            textSize = 16f
            setTextColor(ContextCompat.getColor(this@MainActivity, R.color.colorPrimary))
        }
    }

    override fun onTabUnselected(tab: TabLayout.Tab) {
        val tabText = tab.customView?.findViewById<TextView>(R.id.tabText)
        tabText?.apply {
            textSize = 14f
            setTextColor(ContextCompat.getColor(this@MainActivity, R.color.textGray))
        }
    }

    override fun onTabReselected(tab: TabLayout.Tab) {}
})

4. 进阶:实现下划线跟随动画

如果想要截图中那种下划线平滑跟随Tab宽度变化的效果,可以自定义Indicator:
创建CustomTabIndicator.kt继承自TabLayout的指示器策略:

class CustomTabIndicator(private val tabLayout: TabLayout) : TabLayout.TabIndicatorStrategy {
    private val indicatorView = View(tabLayout.context).apply {
        setBackgroundColor(ContextCompat.getColor(tabLayout.context, R.color.colorPrimary))
        tabLayout.addView(this)
    }

    override fun onMeasure(tabLayout: TabLayout, widthMeasureSpec: Int, heightMeasureSpec: Int) {
        indicatorView.measure(
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
            View.MeasureSpec.makeMeasureSpec(tabLayout.tabIndicatorHeight, View.MeasureSpec.EXACTLY)
        )
    }

    override fun onLayout(tabLayout: TabLayout, left: Int, top: Int, right: Int, bottom: Int) {
        val selectedTab = tabLayout.selectedTab ?: return
        val tabView = selectedTab.view
        indicatorView.layout(tabView.left, tabLayout.height - tabLayout.tabIndicatorHeight, tabView.right, tabLayout.height)
    }

    override fun onTabSelected(tab: TabLayout.Tab) {
        // 添加平滑移动动画
        val tabView = tab.view
        ValueAnimator.ofInt(indicatorView.left, tabView.left, indicatorView.right, tabView.right).apply {
            duration = 300
            addUpdateListener { animator ->
                val values = animator.animatedValue as IntArray
                indicatorView.layout(values[0], indicatorView.top, values[2], indicatorView.bottom)
            }
            start()
        }
    }

    // 其他默认方法可以直接空实现
    override fun onTabUnselected(tab: TabLayout.Tab) {}
    override fun onTabReselected(tab: TabLayout.Tab) {}
}

然后在代码中给TabLayout设置自定义指示器:

tabLayout.setTabIndicatorStrategy(CustomTabIndicator(tabLayout))

内容的提问来源于stack exchange,提问作者Alpha Net

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:05:31