Android 底部导航栏 (BottomNavigationView) 制作教程

在 Android 应用开发中,底部导航栏是非常常见的交互组件,能够让用户快速切换不同的功能模块。本文将详细介绍如何使用 Material Design 组件中的 BottomNavigationView 实现底部导航功能。

目录结构如图

一、布局文件实现

首先,我们需要在 activity_main.xml 中定义主布局结构,主要包含一个用于显示内容的 FrameLayout 和底部导航栏 BottomNavigationView。

XML 复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <!-- 用于显示Fragment内容的容器 -->
    <FrameLayout
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

    <!-- 底部导航栏 -->
    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_nav"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:menu="@menu/bottom_nav_menu" />
</LinearLayout>

二、创建导航菜单

接下来需要创建底部导航栏的菜单文件,在 res/menu 目录下创建 bottom_nav_menu.xml:

XML 复制代码
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/nav_home"
        android:icon="@drawable/ic_home"
        android:title="Home" />
    <item
        android:id="@+id/nav_dashboard"
        android:icon="@drawable/ic_dashboard"
        android:title="Dashboard" />
    <item
        android:id="@+id/nav_notify"
        android:icon="@drawable/ic_notify"
        android:title="Notify" />
</menu>

三、添加导航图标

在 res/drawable 目录下添加三个导航图标文件(可以使用 Vector Asset 创建):

  1. ic_home.xml(首页图标)
XML 复制代码
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24.0"
    android:viewportHeight="24.0">
    <path
        android:fillColor="#FF000000"
        android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z" />
</vector>
  1. ic_dashboard.xml(仪表盘图标)
XML 复制代码
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24.0"
    android:viewportHeight="24.0">
    <path
        android:fillColor="#FF000000"
        android:pathData="M3,13h8L11,3L3,3v10zM3,21h8v-6L3,15v6zM13,21h8L21,11h-8v10zM13,3v6h8L21,3h-8z" />
</vector>
  1. ic_notify.xml(通知图标)
XML 复制代码
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24.0"
    android:viewportHeight="24.0">
    <path
        android:fillColor="#FF000000"
        android:pathData="M12,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.9,2 2,2zM18,16v-5c0,-3.07 -1.63,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.64,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2z" />
</vector>

四、创建 Fragment 布局

我们需要为三个导航项创建对应的 Fragment 布局文件:

  1. fragment_home.xml(首页布局):
XML 复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="首页"
        android:textSize="24sp" />
</LinearLayout>
  1. fragment_dashboard.xml(仪表盘布局):
复制代码
```XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="仪表盘"
        android:textSize="24sp" />
</LinearLayout>
```
  1. fragment_notify.xml(通知布局):
复制代码
```XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="通知"
        android:textSize="24sp" />
</LinearLayout>
```

### 五、创建 Fragment 类

为每个布局创建对应的 Fragment 类:
  1. HomeFragment.java:
复制代码
```java
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;

public class HomeFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // 加载布局文件
        return inflater.inflate(R.layout.fragment_home, container, false);
    }
}
```

其他代码也一样 注意修改 类名和 布局选择

六、实现 MainActivity 逻辑

最后,在 MainActivity 中实现底部导航栏的切换逻辑:

java 复制代码
package com.example.demo01;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import com.google.android.material.bottomnavigation.BottomNavigationView;
public class MainActivity extends AppCompatActivity {
    private BottomNavigationView bottomNav;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bottomNav = findViewById(R.id.bottom_nav);
        // 默认首页
        loadFragment(new HomeFragment());
        // 1.2.1 旧版监听接口
        bottomNav.setOnNavigationItemSelectedListener(
                item -> {
                    Fragment selected = null;
                    int id = item.getItemId();

                    if (id == R.id.nav_home) {
                        selected = new HomeFragment();
                    } else if (id == R.id.nav_dashboard) {
                        selected = new DashboardFragment();
                    } else if (id == R.id.nav_notify) {
                        selected = new NotifyFragment();
                    }
                    return loadFragment(selected);
                });
    }
    private boolean loadFragment(Fragment f) {
        if (f == null) return false;
        getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.fragment_container, f)
                .commit();
        return true;
    }
}

七、注意事项

  1. 底部导航栏的图标和文字颜色可以通过主题进行自定义

  2. 当导航项超过 3 个时,BottomNavigationView 会默认使用移位模式,可通过代码禁用

相关推荐
xiangpanf2 小时前
Laravel 10.x重磅升级:五大核心特性解析
android
robotx5 小时前
安卓线程相关
android
消失的旧时光-19435 小时前
Android 面试高频:JSON 文件、大数据存储与断电安全(从原理到工程实践)
android·面试·json
dalancon6 小时前
VSYNC 信号流程分析 (Android 14)
android
dalancon6 小时前
VSYNC 信号完整流程2
android
dalancon6 小时前
SurfaceFlinger 上帧后 releaseBuffer 完整流程分析
android
用户69371750013847 小时前
不卷AI速度,我卷自己的从容——北京程序员手记
android·前端·人工智能
程序员Android8 小时前
Android 刷新一帧流程trace拆解
android
墨狂之逸才8 小时前
解决 Android/Gradle 编译报错:Comparison method violates its general contract!
android
阿明的小蝴蝶9 小时前
记一次Gradle环境的编译问题与解决
android·前端·gradle