目录
详细学习:Android 原生 TabLayout 使用全解析,看这篇就够了_android tablayout-CSDN博客
一、使用TabLayout做导航栏(图标+标题)

1、activity布局
XML
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@+id/tabLayout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="74dp"
android:clipToPadding="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:tabIndicatorHeight="0dp"
app:tabMode="fixed"
app:tabRippleColor="@color/color_CCCCCC"
app:tabSelectedTextColor="@color/color_3E3A39" />
</androidx.constraintlayout.widget.ConstraintLayout>
2、创建Tab数据类
Kotlin
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
/**
* @param title tab标签
* @param iconSelectRes 选中图标
* @param iconUnselectRes 未选中图标
* @param fragment 显示的Fragment
*/
data class TabInfo(
@StringRes val title: Int,
@DrawableRes val iconSelectRes: Int,
@DrawableRes val iconUnselectRes: Int,
val fragment: Fragment
)
3、逻辑部分
Kotlin
import android.os.Bundle
import android.view.LayoutInflater
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter
import com.google.android.material.tabs.TabLayoutMediator
class MainActivity : AppCompatActivity() {
private val binding by lazy {
ActivityMainBinding.inflate(LayoutInflater.from(this))
}
private val tabs by lazy {
listOf(
TabInfo(R.string.tab_home, R.drawable.ic_home, R.drawable.ic_home_not, HomeFragment()),
TabInfo(R.string.tab_withdraw, R.drawable.ic_withdraw, R.drawable.ic_withdraw_not, WithdrawFragment()),
TabInfo(R.string.tab_mine, R.drawable.ic_mine, R.drawable.ic_mine_not, MineFragment())
)
}
private var selectTabIndex = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
initTab()
}
fun initTab() {
val myAdapter = MyFragmentAdapter(this)
binding.fragmentContainer.apply {
adapter = myAdapter
TabLayoutMediator(binding.tabLayout, this) { tab, position ->
val tabInfo = myAdapter.getTabInfo(position)
tab.text = getString(tabInfo.title)
tab.icon = ContextCompat.getDrawable(
this@MainActivity,
if (position == selectTabIndex) tabInfo.iconSelectRes else tabInfo.iconUnselectRes
)
// 添加点击监听
tab.view.setOnClickListener {
selectTabIndex = position
tabs.forEachIndexed { index, info ->
val tab = binding.tabLayout.getTabAt(index)
tab?.icon = ContextCompat.getDrawable(
this@MainActivity,
if (index == selectTabIndex) tabs[index].iconSelectRes else tabs[index].iconUnselectRes
)
}
}
}.attach()
}
}
inner class MyFragmentAdapter(fragmentActivity: FragmentActivity) :
FragmentStateAdapter(fragmentActivity) {
override fun getItemCount(): Int = tabs.size
override fun createFragment(position: Int): Fragment {
return tabs[position].fragment
}
fun getTabInfo(position: Int): TabInfo {
return tabs[position]
}
}
}
二、做切换卡片(标题+指示器)

1、创建相关资源
指定宽高的指示器drawable文件record_tab_indicator.xml,默认是满TabItem宽度的
XML
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:width="37dp"
android:height="6dp"
android:gravity="center">
<shape>
<corners android:radius="3dp" />
</shape>
</item>
</layer-list>
在styles.xml中创建标签文本样式
XML
<resources>
<style name="recordTabText">
<item name="android:textSize">18sp</item>
<item name="android:textStyle">bold</item>
<item name="android:textColor">@color/color_333333</item>
</style>
</resources>
2.布局中设置指示器和文本样式
XML
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabIndicator="@drawable/record_tab_indicator"
app:tabIndicatorColor="#FC3F6B"
app:tabMode="fixed"
app:tabTextAppearance="@style/recordTabText"/>
3.逻辑
Kotlin
binding.tabLayout.apply {
addTab(tabLayout.newTab().setText(getString(R.string.gold_record)))
addTab(tabLayout.newTab().setText(getString(R.string.withdraw_record)))
addOnTabSelectedListener(
object : TabLayout.OnTabSelectedListener {
override fun onTabSelected(tab: TabLayout.Tab?) {
type = tab?.position ?: 0
//切换tab逻辑
}
override fun onTabUnselected(tab: TabLayout.Tab?) {}
override fun onTabReselected(tab: TabLayout.Tab?) {}
}
)
tabLayout.getTabAt(1)?.select() //指定选中tab
}