android compose NavigationBar 导航栏 使用

android compose NavigationBar 导航栏 使用

使用 NavigationBarNavigationBarItem 可组合项来 实现目的地切换逻辑。每个 NavigationBarItem 都代表一个单独的目的地。

NavigationBarItem 包含以下关键参数:

  • selected:确定当前项是否以视觉方式突出显示。
  • onClick():定义用户点击该项时要执行的操作。用于处理导航事件、更新所选项状态或加载相应内容的逻辑属于此处。
  • label:在项内显示文本。可选。
  • icon:在项内显示图标。可选。

要点

  • NavigationBar 显示一系列项,每个项对应一个 Destination
  • val navController = rememberNavController() 会创建并记住 NavHostController 的实例,该实例用于管理 NavHost 中的导航。
  • var selectedDestination by rememberSaveable { mutableIntStateOf(startDestination.ordinal) } 用于管理所选项的状态。
    • startDestination.ordinal 用于获取 Destination.SONGS 枚举条目的数字索引(位置)。
  • 点击某个项时,系统会调用 navController.navigate(route = destination.route) 以导航到相应屏幕。
  • NavigationBarItemonClick lambda 会更新 selectedDestination 状态,以视觉方式突出显示点击的项。
  • 导航逻辑会调用 AppNavHost 可组合项,并传递 navControllerstartDestination,以显示所选屏幕的实际内容。
复制代码
package com.wn.androidcomposedemo1.basegoogle

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Call
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Person
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarDefaults
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.tooling.preview.Preview
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.wn.androidcomposedemo1.ui.theme.AndroidComposeDemo1Theme

/**
 * Author : wn
 * Email : maoning20080808@163.com
 * Date : 2026/6/27 12:43
 * Description :  底部导航栏
 */
class NavigationBarActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContent {
            AndroidComposeDemo1Theme() {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    NavigationBarExample()
                }
            }
        }
    }


    @Preview
    @Composable
    fun NavigationBarExample(){
        val navController = rememberNavController()
        val startDestination = Destination.HOME
        var selectedDestination by rememberSaveable { mutableIntStateOf(0) }

        Scaffold(
            modifier = Modifier.fillMaxSize(),
            bottomBar = {
                NavigationBar(windowInsets = NavigationBarDefaults.windowInsets) {
                    Destination.entries.forEachIndexed { index, destination ->
                        NavigationBarItem(
                            selected = selectedDestination == index,
                            onClick = {
                                navController.navigate(route = destination.route)
                                selectedDestination = index
                            },
                            icon = {
                                Icon(destination.icon,
                                    contentDescription = destination.contentDescription)
                            },
                            label = {
                                Text(destination.label)
                            }
                        )
                    }
                }
            }
        ) { contentPadding ->
            AppNavHost(navController, startDestination, modifier = Modifier.padding(contentPadding))
        }
    }

    @Composable
    fun AppNavHost(
        navController: NavHostController,
        startDestination: Destination,
        modifier: Modifier
    ){
        NavHost(
            navController = navController,
            startDestination = startDestination.route){
            Destination.entries.forEach { destination ->
                composable(destination.route){
                    when(destination){
                        Destination.HOME -> HomeScreen()
                        Destination.CALL -> CallScreen()
                        Destination.PERSON -> PersonScreen()
                    }
                }
            }
        }
    }

    @Composable
    fun HomeScreen(){
        Box(modifier = Modifier.fillMaxSize(),
            contentAlignment = Alignment.Center){
            Text("首页")
        }
    }

    @Composable
    fun CallScreen(){
        Box(modifier = Modifier.fillMaxSize(),
            contentAlignment = Alignment.Center){
            Text("电话页面")
        }
    }

    @Composable
    fun PersonScreen(){
        Box(modifier = Modifier.fillMaxSize(),
            contentAlignment = Alignment.Center){
            Text("个人页面")
        }
    }
}



enum class Destination(
    val route : String,
    val label : String,
    val icon : ImageVector,
    val contentDescription: String
){
    HOME("home", "首页", Icons.Default.Home, "首页描述"),
    CALL("call", "电话", Icons.Default.Call, "电话描述"),
    PERSON("person", "个人", Icons.Default.Person, "个人描述")
}