【问题标题】:Will navController.navigate() cause Android recomposition when I use Compose?使用 Compose 时,navController.navigate() 会导致 Android 重组吗?
【发布时间】:2021-12-27 02:17:48
【问题描述】:

代码A来自官方示例projectend分支。

当我点击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


    【解决方案1】:

    是的,navigate() 在重新创建 UI 时肯定会导致重新组合。

    是的,val currentScreen = RallyScreen.fromRoute(backstackEntry.value?.destination?.route) 将被重新执行,因为 backstackEntry 正在被观察为状态,并且它的值会在您导航时发生变化。这就是为什么RallyApp 可组合也将被重新组合的原因。所以当它再次执行时,currentScreen 的值会被更新。

    【讨论】:

      猜你喜欢
      • 2015-03-25
      • 1970-01-01
      • 1970-01-01
      • 2022-10-14
      • 2011-12-22
      • 1970-01-01
      • 2013-11-21
      • 1970-01-01
      • 2022-11-10
      相关资源
      最近更新 更多