【问题标题】:How to hide bottom bar in Jetpack Compose when using Accompanists` Navigation Animation使用伴奏导航动画时如何在 Jetpack Compose 中隐藏底栏
【发布时间】:2021-08-23 15:43:53
【问题描述】:

情况

我正在使用 KotlinAndroid Jetpack Compose 编写一个非常简单的应用程序

我有一个scaffold,其中包含我的navHost 和一个bottomBar。 我可以使用bottomBar 在三个主屏幕之间导航。 其中一个主屏幕有一个详细信息屏幕,不应显示bottomBar


我的代码

到目前为止,这是小菜一碟:

// MainActivitys onCreate

setContent {
    val navController = rememberAnimatedNavController()
    val navBackStackEntry by navController.currentBackStackEntryAsState()
    val currentRoute = navBackStackEntry?.destination?.route?.substringBeforeLast("/")

    BottomBarNavTestTheme {
        Scaffold(
            bottomBar = {
                if (currentRoute?.substringBeforeLast("/") == Screen.Detail.route) {
                    MyBottomNavigation(
                        navController,
                        currentRoute,
                        listOf(Screen.Dashboard, Screen.Map, Screen.Events) // main screens
                    )
                }
            }
        ) { innerPadding ->
            NavHost( // to be replaced by AnimatedNavHost
                navController = navController,
                startDestination = Screen.Dashboard.route,
                modifier = Modifier.padding(innerPadding)
            ) {
                composable(Screen.Dashboard.route) { DashboardScreen() }
                composable(Screen.Map.route) { MapScreen { navController.navigate(Screen.Detail.route) } }
                composable(Screen.Events.route) { EventsScreen() }
                composable(Screen.Detail.route) { MapDetailScreen() }
            }
        }
    }
}

问题

我想在我的屏幕之间进行转换,所以我使用Accompanists Navigation Animation: 只需将NavHost 替换为AnimatedNavHost

mainScreen 导航到detailScreen 时会出现奇怪的效果:

  1. bottomBar 隐藏
  2. 主屏幕调整大小:(见底部对齐文本)
  3. 详细信息屏幕的动画发生。

这看起来很糟糕,我该如何解决?


解决方案

最佳解决方案如下所示:

  • 主屏幕保留底栏并淡出。
  • 同时进入详情页没有底栏。

【问题讨论】:

  • 您希望动画是什么样的?您的if 检查正在按照您说的做:一旦目的地发生变化(即当您navigate()),立即隐藏底部导航,没有任何动画。
  • 我觉得不错
  • 您是否尝试过使用AnimatedNavHost 而不是NavHost 并看到区别?
  • @hsm59 我正在使用 AnimatedNavHost。抱歉,如果不够清楚:“只需将 NavHost 替换为 AnimatedNavHost。”
  • 这是 AndroidX 团队应该解决的一个有效问题。

标签: android android-jetpack-compose jetpack-compose-accompanist


【解决方案1】:

所以我们采取了解决方法:

  • 在顶层 scaffold 现在不再包含 bottomBar
  • 每个需要它的屏幕现在都有自己的bottomBar

这工作正常,只是bottomBar 的波纹点击不像我们希望的那样平滑(我们正在交换它的中间点击,所以这是意料之中的)

这也解决了一个问题,即屏幕具有可滚动内容,滚动距离在隐藏底部栏时会发生变化,因此滚动距离会有些混乱。

【讨论】:

    【解决方案2】:

    在我的代码中遇到了类似的问题,这就是我解决它的方法; 我使用了淡入淡出,你可以阅读更多https://developer.android.com/jetpack/compose/animation#crossfade 更多关于底部导航的信息来自https://developer.android.com/jetpack/compose/navigation#bottom-nav

    enum class HomeNavType {
        DASHBOARD, ACCOUNT
    }
    
    @Composable
    fun HomeScreen(navController: NavController) {
        val homeNavItemState = rememberSaveable { mutableStateOf(HomeNavType.DASHBOARD) }
        Scaffold(
            content = { HomeContent(homeNavType = homeNavItemState.value , navController)},
            bottomBar = { HomeBottomNavigation(homeNavItemState) }
        )
    }
    
    @Composable
    fun HomeBottomNavigation(homeNavItemState: MutableState<HomeNavType>) {
        BottomNavigation() {
            BottomNavigationItem(
                selected = homeNavItemState.value === HomeNavType.DASHBOARD,
                onClick = {
                    homeNavItemState.value = HomeNavType.DASHBOARD
                },
                icon = {
                    Icon(
                        painter = painterResource(id = R.drawable.ic_dashboard),
                        contentDescription = "Dashboard"
                    )
                },
                label = { Text("Dashboard") },
            )
            BottomNavigationItem(
                selected = homeNavItemState.value === HomeNavType.ACCOUNT,
                onClick = {
                    homeNavItemState.value = HomeNavType.ACCOUNT
                },
                icon = {
                    Icon(
                        painter = painterResource(id = R.drawable.ic_person),
                        contentDescription = "Account"
                    )
                },
                label = { Text("Account") },
            )
        }
    }
    
    @Composable
    fun HomeContent(homeNavType: HomeNavType, navController: NavController) {
        Crossfade(targetState = homeNavType) { navType ->
            when (navType) {
                HomeNavType.DASHBOARD -> DashboardScreen(navController)
                HomeNavType.ACCOUNT -> AccountScreen(navController)
            }
        }
    }
    

    【讨论】:

    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
    猜你喜欢
    • 2022-10-16
    • 1970-01-01
    • 2021-09-28
    • 1970-01-01
    • 2015-06-14
    • 1970-01-01
    • 2022-12-12
    • 1970-01-01
    • 2017-08-23
    相关资源
    最近更新 更多