是否可以在 Android/Jetpack Compose 中预填充导航后台?
我有一个深层链接,可以深入导航层次结构,但是,按后退时,它会导航到根路线。
例子:
Route.Main -> Route.List -> Route.Details(参数:id)
深层链接: https: //mywebsite.com/details/id
当前行为:它使用正确的参数打开 Route.Details,但是,在 onBack 时,它打开 Route.Main
期望的行为:它应该打开 Route.List
我知道我可以手动“编程”此行为,但我更喜欢“配置”它。
android android-navigation android-jetpack-compose jetpack-compose-navigation
在 Navhost 导航期间,我发现可组合屏幕多次重新组合。因此,我的 ViewModel 也多次调用 API 数据源。
@Composable
fun MainView() {
val scaffoldState = rememberScaffoldState(rememberDrawerState(DrawerValue.Closed))
val scope = rememberCoroutineScope()
val navController = rememberNavController()
Scaffold(
scaffoldState = scaffoldState,
topBar = { TopBar(
toolbarTitle = stringResource(id = R.string.app_name),
scope = scope,
scaffoldState = scaffoldState
) },
drawerContent = {
DrawerView(scope = scope, scaffoldState = scaffoldState, navController = navController)
},
) {
NavGraph(navController = navController)
}
}
@Composable
fun NavGraph(navController: NavHostController) {
NavHost(navController, startDestination = NavDrawerItem.Repositories.route) {
composable(NavDrawerItem.Repositories.route) {
RepoListView(getViewModel())
}
composable(NavDrawerItem.EmojiList.route) { …Run Code Online (Sandbox Code Playgroud) android android-jetpack-navigation android-jetpack-compose jetpack-compose-navigation compose-recomposition
我已经尝试了所有可能的方法,看起来没有找到解决方案。
我正在使用带有撰写屏幕的全撰写应用程序,并使用撰写导航在此屏幕之间导航,我有一个场景,我以这种方式进一步导航
屏幕 A > 屏幕 B1 >..> 屏幕 BN > 屏幕 C
现在,在完成屏幕 C 上的功能后,我想弹回屏幕 A,但这次带有一个可选参数,例如:成功
我这样做是为了导航到 A:
val route = "ScreenA?arg={arg}"
// navigating like this
navController.navigate("ScreenA")
// handling
composable(route, arguments = listOf(navArgument("arg") { nullable = true })){
ScreenA()
}
Run Code Online (Sandbox Code Playgroud)
现在,为了从我所在的位置弹回到 ScreenA,我已经这样做了:
navController.popBackStack(
route = route,
inclusive = false
)
Run Code Online (Sandbox Code Playgroud)
我现在想在返回时发送参数。我尝试将路线添加为
ScreenA?arg=success
Run Code Online (Sandbox Code Playgroud)
这在 popBackStack 函数中不起作用,它检查路由的哈希码
popBackStack(createRoute(route).hashCode(), inclusive, saveState)
Run Code Online (Sandbox Code Playgroud)
在这种情况下我的导航失败
我也尝试过将参数设置为后退堆栈条目,但由于它可能是中间的 N Screen,因此无法工作。需要了解我哪里做错了或者是否有办法做到这一点?
从文档中,我看到您可以像这样嵌套导航图:
NavHost(navController, startDestination = "home") {
...
// Navigating to the graph via its route ('login') automatically
// navigates to the graph's start destination - 'username'
// therefore encapsulating the graph's internal routing logic
navigation(startDestination = "username", route = "login") {
composable("username") { ... }
composable("password") { ... }
composable("registration") { ... }
}
...
}
Run Code Online (Sandbox Code Playgroud)
我想知道,如何在路线中传递参数,并使其可供导航图中的所有可组合项使用?
这是我当前的导航图:
navigation(
// I'd like to grab this parameter
route = "dashboard?classId={classId}",
startDestination = Route.ScreenOne.route) {
composable(Route.ScreenOne.route) {
// And then …Run Code Online (Sandbox Code Playgroud) 我的目标是拥有一个LoginScreen可以导航到InternalScreen. 应该InternalScreen有一个底部导航栏,可以导航到内部空间中的多个其他屏幕/路线。
这就是我想象中NavGraph的样子:
- LoginScreen
- internal space
- InternalScreen with BottomNavigation
- some fragment
- some other fragment
Run Code Online (Sandbox Code Playgroud)
我的想法是在可组合项中创建一个Scaffold带有 a 的项目,但我不知道将它放在哪里,因为 said还必须包含 的不同路线。BottomNavigationBarInternalScreenNavGraphNavGraphBottomNavigationBar
我应该如何处理这个问题?如果这个问题已经得到解答,我很抱歉,我找不到有关此特定案例的任何信息。
我正在使用 Jetpack Compose ui 版本1.3.0-beta08和导航撰写版本2.4.0-alpha02,并使用所有新的架构组件运行 Bloom 应用程序。登录成功后,我需要清除所有以前的撰写登录屏幕,但即使添加了popUpTo("HomeScreen"){inclusive = true},当我从主屏幕单击返回时,我的登录屏幕从后台删除,但登录欢迎屏幕未从后台删除。我在撰写导航中遗漏/错误了吗?
composable(Screen.LoginScreen.route) {
LoginScreen {
Log.d("AppMainNavigation", "AppMainNavigation: ${navController.backQueue}")
navController.navigate(Screen.HomeBaseScreen.route){
popUpTo(Screen.LoginScreen.route){
inclusive = true
}
launchSingleTop = true
}
}
}
Run Code Online (Sandbox Code Playgroud)
android android-jetpack-navigation android-jetpack-compose jetpack-compose-navigation
我有一个显示过滤器选项的过滤器对话框:
当我单击“父平台”部分时,我将导航到带有PlatformsScreen两个参数的。第一个参数parent是 int ,第二个参数是 platform ,它是一个 int 数组:
sealed class Screen(val route: String, val arguments: List<NamedNavArgument>) {
object PlatformScreen : Screen(PLATFORM_ROUTE,arguments =
listOf(navArgument("parent", builder = {type = NavType.IntType}),
navArgument("platforms",builder = {type = NavType.IntArrayType})))
}
// click action
@Composable
fun FilterDialog(
modifier: Modifier = Modifier,
viewModel: FilterViewModel,
navigateToPlatformScreen: (Int,Array<Int?>) -> Unit
) {
val filterState by viewModel.filterState.collectAsState()
Row(//other stuff
.clickable {
navigateToPlatformScreen(filterState.parentPlatform?.id ?: -1,
filterState.platforms?.map { it?.id }?.toTypedArray() ?: arrayOf(-1))
}
)
//here is my filter bottom …Run Code Online (Sandbox Code Playgroud) android kotlin android-jetpack-compose jetpack-compose-navigation
我正在尝试为我的订单管理应用程序构建以下导航:
manage_orders/manage_orders/{locationId}
manage_orders/manage_order_details/{orderId}
Run Code Online (Sandbox Code Playgroud)
这是我的导航代码:
internal sealed class Screen(val route: String) {
object ManageOrders : Screen(manage_orders)
}
private sealed class LeafScreen(val route: String) {
fun createRoute(root: Screen): String {
return "${root.route}/$route"
}
object ManageOrders : LeafScreen("manage_orders/{locationId}") {
fun createRoute(root: Screen, locationId: String): String {
return "${root.route}/manage_orders/$locationId"
}
}
object ManageOrderDetails : LeafScreen("manage_order_details/{orderId}") {
fun createRoute(root: Screen, orderId: String): String {
return "${root.route}/manage_order_details/$orderId"
}
}
}
@ExperimentalCoroutinesApi
@Composable
internal fun AppNavigation(
navController: NavHostController,
locationId: String,
modifier: Modifier = Modifier
) {
NavHost( …Run Code Online (Sandbox Code Playgroud) android android-architecture-navigation android-jetpack-compose jetpack-compose-navigation
我检查了此信息https://developer.android.com/jetpack/compose/libraries#hilt-navigation如何注入ViewModel撰写屏幕。
现在我为我的测试应用程序实现了这样的:
NavHost(
navController = navController,
startDestination = startDestination,
modifier = modifier
) {
composable(Screen.Topics.name) {
val parentEntry = remember { navController.getBackStackEntry(Screen.Topics.name) }
val topicsViewModel = hiltViewModel<TopicsViewModel>(parentEntry)
TopicsScreen(
topicsViewModel = topicsViewModel,
openDrawer = openDrawer,
navigateToTopicDetails = { topic -> actions.navigateToTopicsDetails(topic) }
)
}
...
Run Code Online (Sandbox Code Playgroud)
如果我使用会有什么不同吗
val parentEntry = remember { navController.getBackStackEntry(Screen.Topics.name) }
val topicsViewModel = hiltViewModel<TopicsViewModel>(parentEntry)
Run Code Online (Sandbox Code Playgroud)
要不就
val topicsViewModel = hiltViewModel<TopicsViewModel>()
Run Code Online (Sandbox Code Playgroud)
我想只有当我们使用嵌套图并且我们想要获取特定图范围的 ViewModel 时才需要第一个https://developer.android.com/jetpack/compose/navigation#nested-nav
因此,在我的情况下,如果我不使用嵌套图,两种方法的范围是相同的?
那么我可以只用hiltViewModel<TopicsViewModel>()在我的情况下吗?
android android-jetpack-compose dagger-hilt jetpack-compose-navigation
我遇到这个问题,当异步任务执行后给定状态更新时,我必须进行导航。我这样做是这样的:
At ViewModel.kt
fun executeRandomTask() {
viewModelScope.launch {
runAsyncTask()
state = Success
}
}
At Composable.kt
LaunchedEffect(viewModel.state) {
if(viewModel.state is Success) {
navController.navigate("nextScreen")
}
}
Run Code Online (Sandbox Code Playgroud)
然后在下一个屏幕中,我单击后退导航按钮 (onBackPressed),会发生什么情况,效果再次启动。所以我又回到了“nextScreen”。
当我执行下一个解决方法时:
DisposableEffect(viewModel.state) {
if(viewModel.state is Success) {
navController.navigate("nextScreen")
}
onDispose {
viewModel.state = null
}
}
Run Code Online (Sandbox Code Playgroud)
像这样,视图模型状态被清除,它也证明正在发生的事情是导航控制器破坏了前一个屏幕(不确定这是否是预期的行为)。
我不确定我应该做什么来避免这种情况,因为这是一种非常常见的情况,并且在达到某个状态后必须清除状态看起来很脏。
android side-effects android-jetpack-compose jetpack-compose-navigation
jetpack-compose-navigation ×10
android ×9
android-architecture-navigation ×1
dagger-hilt ×1
kotlin ×1
side-effects ×1