现在常用的App主页都会有一个底部导航栏,根据需求也使用过好几种方法进行实现,于是想着还是总结一下,今天还写一个简单的BottomNavigationView方法来实现这个功能
它是android原生的一个底部导航框架,一般和Fragment一起使用。
xml布局:最外层的layout不用管,那是databinding框架的根布局,主要的布局FrameLayout来装载fragment列表,BottomNavigationView实现底部导航栏,最后监听绑定实现点击切换
- <?xml version="1.0" encoding="utf-8"?>
- <layout xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools">
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@color/white"
- android:orientation="vertical">
- <androidx.appcompat.widget.AppCompatTextView //只是个文本
- android:id="@+id/nav_text"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="20dp"
- android:gravity="center"
- android:padding="4dp"
- android:text="BottomNavigationView+Menu+Fragment"
- android:textColor="@color/black"
- android:textSize="18sp"
- android:textStyle="bold" />
-
- <FrameLayout
- android:id="@+id/fragment_container"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_above="@id/nav_menu"
- android:layout_below="@id/nav_text" />
-
- <View //只是个分界线
- android:layout_width="match_parent"
- android:layout_height="0.3dp"
- android:layout_above="@id/nav_menu"
- android:background="@color/tab_color_false"/>
-
- <com.google.android.material.bottomnavigation.BottomNavigationView
- android:id="@+id/nav_menu"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentBottom="true"
- android:background="@color/white"
- app:menu="@menu/nav_menu"
- tools:layout_height="50dp" />
- </RelativeLayout>
- </layout>
其中BottomNavigationView控价下的app:menu属性为BottomNavigationView增加item
它是在menu文件下新增nav_menu布局,如何新建呢?看图

然后选择menu类型,命名就用默认的menu就行了 ,然后

就可以了,然后往里面加item
- <?xml version="1.0" encoding="utf-8"?>
- <menu xmlns:android="http://schemas.android.com/apk/res/android">
- <item
- android:id="@+id/navigation_home"
- android:icon="@drawable/yang_1"
- android:title="首页" />
- <item
- android:id="@+id/navigation_tools"
- android:icon="@drawable/yang_4"
- android:title="工具" />
- <item
- android:id="@+id/navigation_play"
- android:icon="@drawable/yang_5"
- android:title="娱乐" />
- <item
- android:id="@+id/navigation_relax"
- android:icon="@drawable/yang_2"
- android:title="放松" />
- <item
- android:id="@+id/navigation_user_center"
- android:icon="@drawable/yang_3"
- android:title="个人中心" />
- </menu>
这样就把menu创建好了,接下来是Activity里面的代码:
- /**
- * author: LiXiang
- * date: 2022/6/28 8:48 下午
- * description:
- */
- class NavMenuActivity : BaseBindActivity<NavMenuActivityLayoutBinding>() {
-
- override val layout: Int
- get() = R.layout.nav_menu_activity_layout
-
- private lateinit var homeFragment: HomeFragment
- private lateinit var toolsFragment: ToolsFragment
- private lateinit var relaxFragment: RelaxFragment
- private lateinit var meFragment: MineFragment
- private lateinit var playFragment: PlayFragment
- private lateinit var fragments: Array<BaseFragment>
- private var mTextMessage: TextView? = null
-
- //监听Item
- private val mOnNavigationItemSelectedListener: BottomNavigationView.OnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item ->
- when (item.itemId) {
- R.id.navigation_home -> {
- replaceFragment(fragments[0], fragments[0].tag.toString())
- mTextMessage?.text = "第1个fragment"
- return@OnNavigationItemSelectedListener true
- }
- R.id.navigation_tools -> {
- replaceFragment(fragments[1], fragments[1].tag.toString())
- mTextMessage?.text = "第2个fragment"
- return@OnNavigationItemSelectedListener true
- }
- R.id.navigation_play -> {
- replaceFragment(fragments[2], fragments[2].tag.toString())
- mTextMessage?.text = "第3个fragment"
- return@OnNavigationItemSelectedListener true
- }
- R.id.navigation_relax -> {
- replaceFragment(fragments[3], fragments[3].tag.toString())
- mTextMessage?.text = "第4个fragment"
- return@OnNavigationItemSelectedListener true
- }
- R.id.navigation_user_center -> {
- replaceFragment(fragments[4], fragments[4].tag.toString())
- mTextMessage?.text = "第5个fragment"
- return@OnNavigationItemSelectedListener true
- }
- }
- false
- }
-
- override fun initView() {
- val navigation: BottomNavigationView = findViewById(R.id.nav_menu)
- mTextMessage = findViewById(R.id.nav_text)
- navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)
- navigation.itemIconTintList = null
- navigation.itemTextColor = ColorStateList.valueOf(ContextCompat.getColor(this, R.color.black))
- homeFragment = HomeFragment()
- toolsFragment = ToolsFragment()
- relaxFragment = RelaxFragment()
- meFragment = MineFragment()
- playFragment = PlayFragment()
- fragments = arrayOf(homeFragment, toolsFragment, playFragment, relaxFragment, meFragment)
- fragments.forEach {
- addFragment(it, it.tag.toString())
- hideFragment(it)
- }
- showFragment(fragments[0])
- }
-
- //添加Fragment到FragmentList中
- private fun addFragment(fragment: Fragment, tag: String) {
- val fragmentManager = supportFragmentManager
- val transaction: FragmentTransaction = fragmentManager.beginTransaction()
- transaction.add(R.id.fragment_container, fragment, tag)
- transaction.commit()
- }
-
- // 清空fragmentList的所有Fragment,替换成新的Fragment,注意Fragment里面的坑
- private fun replaceFragment(fragment: Fragment, tag: String) {
- val fragmentManager = supportFragmentManager
- val transaction: FragmentTransaction = fragmentManager.beginTransaction()
- transaction.replace(R.id.fragment_container, fragment, tag)
- transaction.commit()
- }
-
- //把Fragment设置成显示状态,但是并没有添加到FragmentList中
- private fun showFragment(fragment: Fragment) {
- val fragmentManager = supportFragmentManager
- val transaction: FragmentTransaction = fragmentManager.beginTransaction()
- transaction.show(fragment)
- transaction.commit()
- }
-
- //把Fragment设置成显示状态,但是并没有添加到FragmentList中
- private fun hideFragment(fragment: Fragment) {
- val fragmentManager = supportFragmentManager
- val transaction: FragmentTransaction = fragmentManager.beginTransaction()
- transaction.hide(fragment)
- transaction.commit()
- }
- }
代码很简单,先把fragment列表添加到FrameLayout容器里,默认展示第一个fragment,通过BottomNavigationView.OnNavigationItemSelectedListener 方法,实现了fragment的切换。
展示效果:

一些总结:
1、 navigation.itemIconTintList = null 这行代码不可缺少,不然你的导航栏的item图片会很丑,这行代码,可以让你的图片正常展示,因为默认的menu有个很丑的类似于蒙层的感觉。
2、navigation.itemTextColor = ColorStateList.valueOf(ContextCompat.getColor(this, R.color.black)) 这个是设置item的文本颜色