当导航到可组合项时,我们如何隐藏 BottomAppBar(包含导航)?

2024-07-01

我有个问题。

问题是,当我导航到“添加问题”屏幕时,我不知道如何隐藏底部应用程序栏。

我需要你的帮助。

这是带有底部应用栏的“我的屏幕”

@Composable
fun Navigation() {
    val navController = rememberNavController()
    val items = listOf(Screen.Home, Screen.Search, Screen.Notifications, Screen.Profil)

    Scaffold(
        bottomBar = {
            bottomAppNavigation(navController = navController, items)

        }
    ) {
        Box(modifier = Modifier.padding(it)) {
            ScreenController(navController = navController)
        }

    }
}

这是我的带有 navHost 的控制器

@ExperimentalComposeUiApi
@Composable
fun ScreenController(navController: NavHostController) {
    NavHost(navController = navController, startDestination = Screen.Home.route) {
        composable(Screen.Home.route) {
            HomeScreen(navController)
        }
        composable(Screen.Search.route) {
            SearchScreen(navController, it)
        }
        composable(Screen.Notifications.route) {

        }
        composable(Screen.Profil.route) {
            user_profil()
        }
        composable("Ask_question") {
            AskScreen(navController)
        }
    }
}

我认为问题是因为这就像活动和片段,我有一个可组合屏幕所在的盒子,我的所有页面都在他里面。


我建议你使用AnimatedVisibility for BottomNavigation小部件,我认为这是最清晰的撰写方式。

  1. 你应该使用remeberSaveable存储 BottomBar 的状态:
// State of bottomBar, set state to false, if current page route is "car_details"
val bottomBarState = rememberSaveable { (mutableStateOf(true)) }
  1. 在可组合函数中我们使用了when对于BottomBar的控制状态,下面我们设置bottomBarState to true,如果我们想显示 BottomBar,否则我们设置bottomBarState to false:
val navController = rememberNavController()

// Subscribe to navBackStackEntry, required to get current route
val navBackStackEntry by navController.currentBackStackEntryAsState()

// Control BottomBar
when (navBackStackEntry?.destination?.route) {
    "cars" -> {
        // Show BottomBar
        bottomBarState.value = true
    }
    "bikes" -> {
        // Show BottomBar
        bottomBarState.value = true
    }
    "settings" -> {
        // Show BottomBar
        bottomBarState.value = true
    }
    "car_details" -> {
        // Hide BottomBar
        bottomBarState.value = false
    }
}

Scaffold(
    bottomBar = {
        BottomBar(
            navController = navController,
            bottomBarState = bottomBarState
        )
    },
    content = {
        NavHost(
            navController = navController,
            startDestination = NavigationItem.Cars.route,
        ) {
            composable(NavigationItem.Cars.route) {
                CarsScreen(
                    navController = navController,
                )
            }
            composable(NavigationItem.Bikes.route) {
                BikesScreen(
                    navController = navController
                )
            }
            composable(NavigationItem.Settings.route) {
                SettingsScreen(
                    navController = navController,
                )
            }
            composable(NavigationItem.CarDetails.route) {
                CarDetailsScreen(
                    navController = navController,
                )
            }
        }
    }
)
  1. Put BottomNavigation inside AnimatedVisibility, set visible价值来自bottomBarState并设置enter and exit动画,就我而言,我使用slideInVertically for enter动画和slideOutVertically for exit动画片:
AnimatedVisibility(
        visible = bottomBarState.value,
        enter = slideInVertically(initialOffsetY = { it }),
        exit = slideOutVertically(targetOffsetY = { it }),
        content = {
            BottomNavigation {
                val navBackStackEntry by navController.currentBackStackEntryAsState()
                val currentRoute = navBackStackEntry?.destination?.route

                items.forEach { item ->
                    BottomNavigationItem(
                        icon = {
                            Icon(
                                painter = painterResource(id = item.icon),
                                contentDescription = item.title
                            )
                        },
                        label = { Text(text = item.title) },
                        selected = currentRoute == item.route,
                        onClick = {
                            navController.navigate(item.route) {
                                popUpTo(navController.graph.findStartDestination().id) {
                                    saveState = true
                                }
                                launchSingleTop = true
                                restoreState = true
                            }
                        }
                    )
                }
            }
        }
    )

MainActivity的完整代码:

package codes.andreirozov.bottombaranimation

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.ExperimentalAnimationApi
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.res.painterResource
import androidx.navigation.NavController
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import codes.andreirozov.bottombaranimation.screens.BikesScreen
import codes.andreirozov.bottombaranimation.screens.CarDetailsScreen
import codes.andreirozov.bottombaranimation.screens.CarsScreen
import codes.andreirozov.bottombaranimation.screens.SettingsScreen
import codes.andreirozov.bottombaranimation.ui.theme.BottomBarAnimationTheme

@ExperimentalAnimationApi
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            BottomBarAnimationApp()
        }
    }
}

@ExperimentalAnimationApi
@Composable
fun BottomBarAnimationApp() {

    // State of bottomBar, set state to false, if current page route is "car_details"
    val bottomBarState = rememberSaveable { (mutableStateOf(true)) }

    BottomBarAnimationTheme {
        val navController = rememberNavController()

        // Subscribe to navBackStackEntry, required to get current route
        val navBackStackEntry by navController.currentBackStackEntryAsState()

        // Control BottomBar
        when (navBackStackEntry?.destination?.route) {
            "cars" -> {
                // Show BottomBar
                bottomBarState.value = true
            }
            "bikes" -> {
                // Show BottomBar
                bottomBarState.value = true
            }
            "settings" -> {
                // Show BottomBar
                bottomBarState.value = true
            }
            "car_details" -> {
                // Hide BottomBar
                bottomBarState.value = false
            }
        }

        Scaffold(
            bottomBar = {
                BottomBar(
                    navController = navController,
                    bottomBarState = bottomBarState
                )
            },
            content = {
                NavHost(
                    navController = navController,
                    startDestination = NavigationItem.Cars.route,
                ) {
                    composable(NavigationItem.Cars.route) {
                        CarsScreen(
                            navController = navController,
                        )
                    }
                    composable(NavigationItem.Bikes.route) {
                        BikesScreen(
                            navController = navController
                        )
                    }
                    composable(NavigationItem.Settings.route) {
                        SettingsScreen(
                            navController = navController,
                        )
                    }
                    composable(NavigationItem.CarDetails.route) {
                        CarDetailsScreen(
                            navController = navController,
                        )
                    }
                }
            }
        )
    }
}

@ExperimentalAnimationApi
@Composable
fun BottomBar(navController: NavController, bottomBarState: MutableState<Boolean>) {
    val items = listOf(
        NavigationItem.Cars,
        NavigationItem.Bikes,
        NavigationItem.Settings
    )

    AnimatedVisibility(
        visible = bottomBarState.value,
        enter = slideInVertically(initialOffsetY = { it }),
        exit = slideOutVertically(targetOffsetY = { it }),
        content = {
            BottomNavigation {
                val navBackStackEntry by navController.currentBackStackEntryAsState()
                val currentRoute = navBackStackEntry?.destination?.route

                items.forEach { item ->
                    BottomNavigationItem(
                        icon = {
                            Icon(
                                painter = painterResource(id = item.icon),
                                contentDescription = item.title
                            )
                        },
                        label = { Text(text = item.title) },
                        selected = currentRoute == item.route,
                        onClick = {
                            navController.navigate(item.route) {
                                popUpTo(navController.graph.findStartDestination().id) {
                                    saveState = true
                                }
                                launchSingleTop = true
                                restoreState = true
                            }
                        }
                    )
                }
            }
        }
    )
}

Result:

不要忘记使用@ExperimentalAnimationApi撰写函数的注释。

Update:使用 Compose 版本 1.1.0 及更高版本@ExperimentalAnimationApi不需要。

2022 年 2 月 22 日更新:我做了一些研究,并更新了第2点。现在我们使用when用于控制bottomBarState.

完整代码可在 gitHub 上找到:https://github.com/AndreiRoze/BottomBarAnimation https://github.com/AndreiRoze/BottomBarAnimation

官方文档中提供的动画示例:https://developer.android.com/jetpack/compose/animation/composables-modifiers https://developer.android.com/jetpack/compose/animation/composables-modifiers

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当导航到可组合项时,我们如何隐藏 BottomAppBar(包含导航)? 的相关文章

随机推荐