如何在Jetpack Compose中向下滚动时隐藏底部导航栏,向上滚动时显示它?

5
我正在创建一个带有底部导航栏的简单应用程序。我想要在组合屏幕中向下滚动时隐藏底部导航栏,并在向上滚动时显示它。
任何帮助都将不胜感激。如果需要更多代码,请告诉我。我已经附上了我认为与此问题相关的所有代码。
这是我的底部导航栏。
@Composable
fun BottomBar(navController: NavController) {

    val items = listOf(
        NavigationItem.Home,
        NavigationItem.Search
    )

    BottomNavigation(
        backgroundColor = MaterialTheme.colors.DarkRed,
        contentColor = Color.White
    ) {

        val navBackStackEntry by navController.currentBackStackEntryAsState()
        val currentRoute = navBackStackEntry?.destination?.route

        items.forEach { item ->
            BottomNavigationItem(
                selected = currentRoute == item.route,
                icon = {
                    Icon(
                        imageVector = item.icon,
                        contentDescription = "Icon",
                        modifier = Modifier.size(28.dp)

                    )
                },
                alwaysShowLabel = false,
                selectedContentColor = Color.White,
                unselectedContentColor = Color.White.copy(0.4f),
                onClick = {
                    navController.navigate(item.route){
                        // Pop up to the start destination of the graph to
                        // avoid building up a large stack of destinations
                        // on the back stack as users select items
                        navController.graph.startDestinationRoute?.let{route ->
                            popUpTo(route){
                                saveState = true
                            }
                        }
                        // Avoid multiple copies of the same destination when
                        // reselecting the same item
                        launchSingleTop = true
                        // Restore state when reselecting a previously selected item
                        restoreState = true
                    }

                }
            )
        }
    }
}

这是我的主屏幕

@Composable
fun MainScreen(){

    val navController = rememberNavController()

    Scaffold(topBar = {
        ActionBar("Books")
    },
        bottomBar = {
            BottomBar(navController)
        }){

        NavigationGraph(navController = navController)
    }
}

而这个NavigationGraph

@Composable
fun NavigationGraph(navController: NavHostController){

    NavHost(navController = navController, startDestination = NavigationItem.Home.route ){

        composable(NavigationItem.Home.route){
            HomeScreen()
        }
        composable(NavigationItem.Search.route){
            SearchScreen()
        }
    }
}

我发现这篇文章包含了你最有可能在寻找的信息:https://proandroiddev.com/how-to-master-swipeable-and-nestedscroll-modifiers-in-compose-bb0635d6a760 - EpicPandaForce
这个回答解决了你的问题吗?在Jetpack Compose上滚动时折叠导航BottomBar - Quanta
2个回答

1
您可以使用LazyListState来跟踪列表的状态,并仅在滚动状态索引为初始状态时显示BottomBar。具体操作如下:
对于LazyColumn
@Composable
fun HomeScreen(scrollState: LazyListState) {

    LazyColumn(
        state = scrollState,
    ) {
        ...
      }
}

对于NavigationGraph:

@Composable
fun NavigationGraph(navController: NavHostController, scrollState: LazyListState){

    NavHost(navController = navController, startDestination = NavigationItem.Home.route ){

        composable(NavigationItem.Home.route){
            HomeScreen(scrollState = scrollState)
        }
        composable(NavigationItem.Search.route){
            SearchScreen()
        }
    }
}

在主屏幕中:
@Composable
fun MainScreen(){

    val navController = rememberNavController()
    val scrollState = rememberLazyListState()

    Scaffold(topBar = {
        ActionBar("Books")
    },
        bottomBar = {
         if(scrollState.firstVisibleItemIndex == 0){ 
                  BottomBar(navController) 
           }
           
        }){

        NavigationGraph(navController = navController, scrollState = scrollState)
    }
}

这样,只有当列表在顶部时,BottomBar才会显示出来。

为了获得更好的性能,请使用“记住当firstVisibleItemIndex == 0时的derivedStateOf”,为了获得更好的视觉效果,请使用AnimatedVisibility。 - Zun
你能详细解释一下如何使用“remember derivedStateOf”吗? - Gautam Hazarika

0
使用Gautam Hazarika的答案,你可以为了更好的性能来做这个。
    val shouldHideBottomBar by remember(scrollState) {
     derivedStateOf { scrollState.firstVisibleItemIndex == 0 
    }  
    Scaffold ( 
              ... 
              bottomBar = { 
                           AnimatedVisibility(
                                visible = shouldHideBottomBar,
                                enter = slideInVertically(animationSpec = tween(durationMillis = 200)),
exit = slideOutVertically(animationSpec = tween(durationMillis = 200)), ) {
                            HomeBottomNavigation(bottomTab, setCurrentBottomTab)
                        }
                    }, 
    ) 
    { ... }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接