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

bz4sfanl  于 2023-06-30  发布在  Kotlin
关注(0)|答案(3)|浏览(116)

我有个问题
问题是,我不知道如何隐藏底部的应用程序栏时,我导航到一个“添加问题”屏幕。
我需要你的帮助。
这是MyScreen,底部是应用程序栏

@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)
        }
    }
}

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

apeeds0o

apeeds0o1#

我建议你使用AnimatedVisibilityBottomNavigation部件,我认为这是最清晰的方式组成.
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设置为true,如果我们想显示BottomBar,否则我们将bottomBarState设置为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.将BottomNavigation放入AnimatedVisibility中,从bottomBarState设置visible值,并设置enterexit动画,在我的例子中,我使用slideInVerticallyenter动画,slideOutVerticallyexit动画:

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
                            }
                        }
                    )
                }
            }
        }
    )
}

结果:

不要忘记使用@ExperimentalAnimationApi注解来编写函数。

**更新:**Compose 1.1.0及以上版本@ExperimentalAnimationApi不需要。
**22.02.2022更新:**我做了一些研究,并更新了第2点。现在我们使用when来控制bottomBarState

完整代码在gitHub上提供:https://github.com/AndreiRoze/BottomBarAnimation
官方文档中提供的动画示例:https://developer.android.com/jetpack/compose/animation/composables-modifiers

toe95027

toe950272#

如果你想隐藏BottomBar,就不要输出它。
类似于:

Scaffold(
    bottomBar = {
        if (currentRoute != "xxxx") {
            BottomAppBar() {
               //....
            }
        }
    },

其中currentRoute是(至少使用Navigation Compose 2.4.0-alpha 01):

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

jmo0nnb33#

val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination?.route in bottomNavItemsList.map { it.route }
Scaffold(
    bottomBar = {
        if (currentDestination) {
            //show
        }
    }
) { innerPaddingModifier ->
    //TODO
}

相关问题