相关疑难解决方法(0)

Jetpack Compose + 导航 - navigate() 上的无限循环

我正在使用 Jetpack Compose + Navigation(单一活动,无片段),并且我正在尝试执行如下导航路线:

SplashScreen---(延迟)---> AuthScreen---(如果成功)-->MainScreen

navigate()不幸的是,当我执行登录时,可组合项中的函数LoginScreen会导致无限循环。我不明白我是否正在触发重组或会发生什么。不幸的是,很难共享所有代码,但请记住:

  • 这个问题似乎与LoginScreenMainScreen组合项无关(您可以假设它们只是一个简单的Text可组合项)
  • 似乎也没有什么关系NavigationGraph。事实上,如果我只是进行SplashScreen-->MainScreen转换,就不会出现问题
  • 如果我删除该行,navController.navigate("main")则不再有循环;
  • 该代码基于(几乎复制粘贴)示例

这是AuthScreen出现问题的代码。

@Composable
fun AuthScreen(navController: NavController) {
    val signInRequestCode = 1
    val context = LocalContext.current

    val mSignInViewModel: SignInGoogleViewModel = viewModel(
        factory = SignInGoogleViewModelFactory(context.applicationContext as Application)
    )

    val state = mSignInViewModel.googleUser.observeAsState()
    val user = state.value

    val isError = rememberSaveable { mutableStateOf(false) }


    val authResultLauncher =
        rememberLauncherForActivityResult(contract …
Run Code Online (Sandbox Code Playgroud)

infinite-loop android-jetpack-navigation android-jetpack-compose

6
推荐指数
1
解决办法
2907
查看次数

Jetpack Compose,使用 NavHost 导航时可变状态会导致无限重组

这是导致无限重组问题的代码

主要活动

class MainActivity : ComponentActivity() {
    
     override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        setContent {
                val navController = rememberNavController()
                val viewModel : MainViewModel by viewModel()
                val state by viewModel.state.observeAsState()

                NavHost(navController = navController, startDestination = "firstScreen") {
                    composable("firstScreen") { FirstScreen(
                        navigate = {
                        navController.navigate("secondScreen")
                    }, updateState = {
                            viewModel.getState()
                       },
                       state

                    )}

                    composable("secondScreen") { SecondScreen() }
                }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

视图模型

class MainViewModel : ViewModel() {

    //var state = MutableStateFlow(0)

    private val _state = MutableLiveData(0)
    val state: LiveData<Int> = _state

    fun …
Run Code Online (Sandbox Code Playgroud)

android kotlin android-jetpack-compose jetpack-compose-navigation compose-recomposition

5
推荐指数
1
解决办法
1781
查看次数

ViewModel 使用 JetpackCompose 触发导航

在 Android 中,我经常想要导航以响应 ViewModel 的状态更改。(例如,成功的身份验证会触发导航到用户的主屏幕。)

最佳实践是从 ViewModel 内触发导航吗?是否有有意的机制来触发可组合项中的导航以响应 ViewModel 状态更改?

使用 Jetpack Compose 处理此用例的过程并不明显。如果我尝试类似以下示例的操作,将会发生导航,但我导航到的目的地将无法正常运行。我相信这是因为在调用导航之前不允许完成原始的可组合函数。

// Does not behave correctly.
@Composable fun AuthScreen() {
    val screenState = viewModel.screenState.observeAsState()
    if(screenState.value is ScreenState.UserAuthenticated){
        navController.navigate("/gameScreen")
    } else {
        LoginScreen()
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我使用 LaunchedEffect ,我确实会观察到正确的行为,如下所示:

// Does behave correctly.
@Composable fun AuthScreen() {
    val screenState = viewModel.screenState.observeAsState()
    if(screenState.value is ScreenState.UserAuthenticated){
        LaunchedEffect(key1 = "test") {
            navController.navigate("$/gameScreen")
        }
    } else {
        LoginScreen()
    }
}
Run Code Online (Sandbox Code Playgroud)

它是否正确?LaunchedEffect 的文档说明如下,但我并不是 100% 清楚其含义:

当 LaunchedEffect 进入组合时,它将启动块到组合的 CoroutineContext 中。当 LaunchedEffect 用不同的 key1、key2 或 …

android android-jetpack-compose jetpack-compose-navigation compose-recomposition

5
推荐指数
1
解决办法
1319
查看次数