Jetpack Compose NavHost 重新组合可组合多次的问题

25

我发现在使用Navhost compose导航时,可组合屏幕会被多次重新组合

以下示例展示了如何将导航与日志集成以标识函数被调用的次数:

internal sealed class Screen(val route: String) {
  object Splash : Screen("splash")
  object Login : Screen("login")
  object Credentials : Screen("credentials/{type}") {
    fun createRoute(type: String) = "credentials/$type"
  }
}

@Composable
fun HostNavGraph(
  modifier: Modifier = Modifier,
  startDestination: String = Splash.route,
) {
  val navController = rememberNavController()
  val vm: CredentialsViewModel = getViewModel()
  NavHost(navController = navController, startDestination = startDestination, modifier = modifier) {
    composable(route = Splash.route) {
      Log.e("composable", " Splash")
      SplashScreen(openLogin = {
        navController.navigate(Login.route)
      }, openRegistration = { type ->
        navController.navigate(Credentials.createRoute(type))
      })
    }
    composable(route = Login.route) {
      Log.e("composable", " Login")
      val context = LocalContext.current
      LoginScreen(openRegistration = { type ->
        navController.navigate(Credentials.createRoute(type))
        {
          popUpTo(Splash.route) { inclusive = false }
        }

      }, openWebView = {
        openWebView(context, it)
      })
    }
    //..
  }
}

运行代码后,打开闪屏一次和登录屏幕一次后,导航的行为方式如下所示:

15:05:14 E/composable:  Splash 
15:05:14 E/composable:  Splash 
15:05:25 E/composable:  Splash 
15:05:25 E/composable:  Login  
15:05:26 E/composable:  Splash 
15:05:26 E/composable:  Login  
15:05:26 E/composable:  Login  

我还尝试了一些使用Navigation compose的Google示例,它表现出相同的方式,那么这是一种意图的行为吗?还是一个bug?
navigation_version = '2.4.0-alpha08'


2
有关此问题的任何解决方案? - LMaker
1
你是怎么解决这个问题的? - yoonhok
请指导我如何解决这个问题。 - Bolt UIX
1
这个问题在https://issuetracker.google.com/issues/225987040被标记为不会修复。 - chen
2个回答

8

我不确定,但我认为NavHost在转换时有内置的动画。而且有了动画,重新组合可能会频繁发生,甚至每一帧都会发生。

可组合函数可能会经常运行,就像每一帧动画一样频繁。

**Android compose


0
这不是一个bug。NavHost是一个可组合的,所以自然可以被组合和重新组合多次!如果你想在可组合的生命周期中执行一次性操作,可以使用LaunchedEffect。
composable(route = Login.route) {
  LaunchedEffect(key){ // relaunched every time its parameter changes
      //It's a good idea to pass the user ID as an argument and use it as the key
      Log.e("composable", " Login")
      }
  ...
  })

Log.e() 是一个副作用,因为它会影响到可组合函数范围之外的状态。副作用是一种不直接影响用户界面的操作,比如日志记录。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接