如何在Jetpack Compose(Material3)中设置底部导航栏固定在页面底部
Hey there! Let's get that bottom navigation bar pinned firmly to the bottom of your screen the right way. The issue with your current code is that you’ve placed the NavigationBar inside the content slot of Scaffold—this slot is meant for your main screen content, so putting the nav bar there won’t keep it fixed in the bottom position as you want.
The Correct Approach: Use Scaffold's Dedicated bottomBar Slot
Jetpack Compose's Scaffold component has a built-in bottomBar parameter specifically designed for elements like bottom navigation bars. Using this slot guarantees the bar stays anchored to the bottom, regardless of what’s happening in your main content area.
Here’s your modified code with the fix applied:
import androidx.compose.foundation.background 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.ArrowBack import androidx.compose.material.icons.filled.Favorite import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.navigation.NavController import io.material.compose.ui.theme.Purple40 @OptIn(ExperimentalMaterial3Api::class) @Composable fun NavigationBarDemoSample(navController: NavController) { var selectedItem by remember { mutableStateOf(0) } val items = listOf("Songs", "Artists", "Playlists") Scaffold( topBar = { CenterAlignedTopAppBar( title = { Text("Navigation Bar") }, modifier = Modifier.background(Purple40), navigationIcon = { IconButton(onClick = { navController.navigateUp() }) { Icon( imageVector = Icons.Filled.ArrowBack, contentDescription = "Back button" ) } }, ) }, // Move NavigationBar to the dedicated bottomBar slot to fix its position bottomBar = { NavigationBar { items.forEachIndexed { index, item -> NavigationBarItem( icon = { Icon(Icons.Filled.Favorite, contentDescription = null) }, label = { Text(item) }, selected = selectedItem == index, onClick = { selectedItem = index } ) } } }, content = { paddingValues -> // Your main screen content belongs here // Apply paddingValues to avoid content being blocked by TopAppBar and BottomBar Box( modifier = Modifier .fillMaxSize() .padding(paddingValues) ) { // Add your actual content components here (e.g., LazyColumn, Text, etc.) Text(text = "Current Screen: ${items[selectedItem]}") } } ) }
Key Changes Breakdown:
- Relocated
NavigationBartobottomBar: This slot signalsScaffoldto render the bar at the bottom and keep it fixed, no matter how your main content scrolls or changes. - Applied
paddingValuesto content: Thecontentlambda receives aPaddingValuesobject that automatically accounts for the height of theTopAppBarandBottomBar. Using this padding ensures your main content never gets hidden behind these UI elements. - Separated concerns: Now the
contentslot is solely for your screen’s main content, which follows Compose’s best practices for UI organization.
Quick Tip:
If you’re using scrollable content (like LazyColumn) in the content slot, make sure to pass the paddingValues to its contentPadding parameter too—this prevents the last items in your list from being blocked by the bottom navigation bar.
内容的提问来源于stack exchange,提问作者Bolt UIX

