【发布时间】:2021-12-27 02:17:48
【问题描述】:
代码A来自官方示例project的end分支。
当我点击UI的Tab时,App会显示对应的UI,当前的Tab会被标记为不同的样式。
在 Overview.name 选项卡 UI 页面中,如果我单击帐户项,代码 composable(Overview.name) {... onAccountClick = { name -> navigateToSingleAccount(navController, name) } 会将其导航到 composable( route = "$accountsName/{name}", ..) UI 和 Accounts.name被标记为当前标签。
让我感到困惑的是,为什么 Android 可以将 Accounts.name 作为当前选项卡,你能告诉我吗? navController.navigate() 会导致 Android recomposition 吗? val currentScreen = RallyScreen.fromRoute(backstackEntry.value?.destination?.route) 也被重新执行了吗?
代码 A
@Composable
fun RallyApp() {
RallyTheme {
val allScreens = RallyScreen.values().toList()
val navController = rememberNavController()
val backstackEntry = navController.currentBackStackEntryAsState()
val currentScreen = RallyScreen.fromRoute(backstackEntry.value?.destination?.route)
Scaffold(
topBar = {
RallyTabRow(
allScreens = allScreens,
onTabSelected = { screen ->
navController.navigate(screen.name)
},
currentScreen = currentScreen
)
}
) { innerPadding ->
RallyNavHost(navController, modifier = Modifier.padding(innerPadding))
}
}
}
@Composable
fun RallyNavHost(navController: NavHostController, modifier: Modifier = Modifier) {
NavHost(
navController = navController,
startDestination = Overview.name,
modifier = modifier
) {
composable(Overview.name) {
OverviewBody(
onClickSeeAllAccounts = { navController.navigate(Accounts.name) },
onClickSeeAllBills = { navController.navigate(Bills.name) },
onAccountClick = { name ->
navigateToSingleAccount(navController, name)
},
)
}
composable(Accounts.name) {
AccountsBody(accounts = UserData.accounts) { name ->
navigateToSingleAccount(navController = navController, accountName = name)
}
}
composable(Bills.name) {
...
}
val accountsName = Accounts.name
composable(
route = "$accountsName/{name}",
arguments = listOf(
navArgument("name") {
type = NavType.StringType
}
),
deepLinks = listOf(
navDeepLink {
uriPattern = "rally://$accountsName/{name}"
}
),
) { entry ->
val accountName = entry.arguments?.getString("name")
val account = UserData.getAccount(accountName)
SingleAccountBody(account = account)
}
}
}
private fun navigateToSingleAccount(navController: NavHostController, accountName: String) {
navController.navigate("${Accounts.name}/$accountName")
}
enum class RallyScreen(
val icon: ImageVector,
) {
Overview(
icon = Icons.Filled.PieChart,
),
Accounts(
icon = Icons.Filled.AttachMoney,
),
Bills(
icon = Icons.Filled.MoneyOff,
);
companion object {
fun fromRoute(route: String?): RallyScreen =
when (route?.substringBefore("/")) {
Accounts.name -> Accounts
Bills.name -> Bills
Overview.name -> Overview
null -> Overview
else -> throw IllegalArgumentException("Route $route is not recognized.")
}
}
}
【问题讨论】:
标签: android kotlin android-jetpack-compose