我有一个带有Jetpack撰写的屏幕,它有一个底部导航和一个导航主机。
在某个时刻,我向该屏幕返回某个值,其效果必须是它应该导航到其中一个选项卡。
如果我只是使用navController.导航(目标)
,那么我有以下错误:
所以我想这不是正确的方法。
如何使用NavController以编程方式导航?
===
编辑:失败的代码:
const valMAIN_COMPOSABLE_ID="main"
sealed class MainTabNavigation(
val route: String,
@StringRes val resourceId: Int,
@DrawableRes val drawableId: Int
) {
object Tab1 : MainTabNavigation("tab1", R.string.shop_tabName, R.drawable.tab1)
object Tab2 :
MainTabNavigation("tab2", R.string.wardrobe_tabName, R.drawable.tab2)
object Tab3 : MainTabNavigation("tab3", R.string.cart_tabName, R.drawable.tab3)
object Tab4 : MainTabNavigation("tab4", R.string.profile_tabName, R.drawable.tab4)
}
private val navItems = listOf(
MainTabNavigation.Tab1, MainTabNavigation.Tab2,
MainTabNavigation.Tab3, MainTabNavigation.Tab4
)
@Composable
fun MainScreen(navController: NavController) {
val mainNavController = rememberNavController()
var goToTab2 = false
val commManager by inject<ComposableCommManager>()
val comm = commManager.readComm(MAIN_COMPOSABLE_ID)
comm?.let {
if (it.communication == "go_to_tab2") {
goToTab2 = true
}
}
if (goToTab2) {
// TODO This line fails
mainNavController.navigate(MainTabNavigation.Tab3.route)
}
Scaffold(
modifier = Modifier.systemBarsPadding(),
bottomBar = {
BottomNavigation(
backgroundColor = Color.White,
contentColor = MaterialTheme.colors.primary
) {
val navBackStackEntry by mainNavController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
navItems.forEach { tab ->
BottomNavigationItem(
icon = {
Icon(
painterResource(id = tab.drawableId),
contentDescription = null
)
},
label = { Text(stringResource(tab.resourceId)) },
alwaysShowLabel = false,
selected = currentDestination?.hierarchy?.any { it.route == tab.route } == true,
onClick = {
mainNavController.navigate(tab.route) {
popUpTo(mainNavController.graph.findStartDestination().id) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
}
)
}
}
}
) { innerPadding ->
NavHost(
mainNavController,
startDestination = if (goToTab2) {
MainTabNavigation.Tab3.route
} else {
startMainDestination
},
Modifier.padding(innerPadding)
) {
composable(MainTabNavigation.Tab1.route) {
ShopTab(navController)
}
composable(MainTabNavigation.Tab2.route) {
WardrobeTab(navController, mainNavController)
}
composable(MainTabNavigation.Tab3.route) {
CartTab(navController, mainNavController)
}
composable(MainTabNavigation.Tab4.route) {
ProfileTab(navController)
}
}
}
}
if (goToTab2) {
mainNavController.navigate(MainTabNavigation.Tab3.route)
}
在jetpack Comment中,你不能使用这样的代码,因为每次在recomposion中,代码都会重新运行。你必须把那部分放在可点击的地方。或者把你的代码放在“命令读取”中查看模型,并在每个ON_RESUME检查那个值。
或者在ON_RESUME块中读取该值(但viewModel会更好)。
@Composable
fun OnLifecycleEvent(onEvent: (owner: LifecycleOwner, event: Lifecycle.Event) -> Unit) {
val eventHandler = rememberUpdatedState(onEvent)
val lifecycleOwner = rememberUpdatedState(LocalLifecycleOwner.current)
DisposableEffect(lifecycleOwner.value) {
val lifecycle = lifecycleOwner.value.lifecycle
val observer = LifecycleEventObserver { owner, event ->
eventHandler.value(owner, event)
}
lifecycle.addObserver(observer)
onDispose {
lifecycle.removeObserver(observer)
}
}
}
像这样使用它
OnLifecycleEvent { _, event ->
when (event) {
Lifecycle.Event.ON_RESUME -> {
mainPageViewModel.setEvent(MainPageContract.Event.OnResume)
}
else -> Unit
}
}