Android 底部导航栏(一、BottomNavigationView+Menu+Fragment)

现在常用的App主页都会有一个底部导航栏,根据需求也使用过好几种方法进行实现,于是想着还是总结一下,今天还写一个简单的BottomNavigationView方法来实现这个功能

Android 底部导航栏(二、自定义View+Fragment)_&岁月不待人&的博客-CSDN博客

Android 底部导航栏(三、ViewPager+TabLayout+Fragment)简单易懂_&岁月不待人&的博客-CSDN博客_android 获取底部导航栏

Android 底部导航栏(四、ViewPager+RadioGroup+Fragment)简单易懂_&岁月不待人&的博客-CSDN博客

一、什么是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的文本颜色

需要源码请私聊嘞

好的,以下是一个简单的 Android 应用程序,其中包括一个底部导航栏BottomNavigationView)。 首先,我们需要在 `build.gradle` 文件中添加 `implementation 'com.google.android.material:material:1.2.1'`,这将为我们提供 Material Design 库,其中包括 BottomNavigationView。 接下来,我们需要在 `activity_main.xml` 文件中添加一个 BottomNavigationView: ```xml <com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/bottom_navigation" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" app:menu="@menu/bottom_navigation_menu" /> ``` `menu` 属性是一个指向我们的菜单资源文件的引用,我们需要在 `res` 文件夹下创建一个名为 `menu` 的文件夹,并在其中创建一个名为 `bottom_navigation_menu.xml` 的文件,它应该如下所示: ```xml <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/navigation_home" android:icon="@drawable/ic_home" android:title="@string/title_home" /> <item android:id="@+id/navigation_dashboard" android:icon="@drawable/ic_dashboard" android:title="@string/title_dashboard" /> <item android:id="@+id/navigation_notifications" android:icon="@drawable/ic_notifications" android:title="@string/title_notifications" /> </menu> ``` 现在,我们需要在我们的 `MainActivity` 中使用 BottomNavigationView。以下是 MainActivity 的完整代码: ```java public class MainActivity extends AppCompatActivity { private BottomNavigationView bottomNavigationView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bottomNavigationView = findViewById(R.id.bottom_navigation); bottomNavigationView.setOnNavigationItemSelectedListener(navListener); getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new HomeFragment()).commit(); } private BottomNavigationView.OnNavigationItemSelectedListener navListener = new BottomNavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { Fragment selectedFragment = null; switch (item.getItemId()) { case R.id.navigation_home: selectedFragment = new HomeFragment(); break; case R.id.navigation_dashboard: selectedFragment = new DashboardFragment(); break; case R.id.navigation_notifications: selectedFragment = new NotificationsFragment(); break; } getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, selectedFragment).commit(); return true; } }; } ``` 我们在 `onCreate` 方法中获取 BottomNavigationView,并为其设置一个 `OnNavigationItemSelectedListener`,以便在用户选择某个导航项时切换 Fragment。我们还在 `onCreate` 方法中添加了一个名为 `HomeFragment` 的 Fragment,这是我们默认显示的 Fragment。 现在,我们需要为每个导航项创建一个 Fragment。以下是我们的三个 Fragment: ```java public class HomeFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_home, container, false); } } public class DashboardFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_dashboard, container, false); } } public class NotificationsFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment return inflater.inflate(R.layout.fragment_notifications, container, false); } } ``` 最后,我们需要创建我们的三个 Fragment 布局文件。这些布局文件可以包含任何你想要的内容,我将使用一个简单的 TextView 演示: ```xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/text_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="Home Fragment" /> </RelativeLayout> ``` ```xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/text_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="Dashboard Fragment" /> </RelativeLayout> ``` ```xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/text_view" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:text="Notifications Fragment" /> </RelativeLayout> ``` 这样,我们就完成了一个简单的 Android 应用程序,其中包括一个底部导航栏
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

&岁月不待人&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值