我要在我的应用程序中实现注册,在填写完相应的字段后,我单击一个按钮,该按钮将向API发出注册请求.同时,我放置了一个加载视图,当我收到成功的响应时,我执行到入网屏幕的导航.问题是,导航控制器总是运行导航并多次执行导航和弹出窗口,而实际上它应该只执行一次.我总是在日志(log)中收到这样的警告:Ignoring popBackStack to destination 29021787 as it was not found on the current back stack,并且我无法在OnBoardingScreen中进行任何点击或聚焦.

我的代码是:

val uiState by registerViewModel.uiState.collectAsState()

when (uiState) {
        is BaseViewState.Data -> {
            navController.navigate(NavigationItem.OnBoarding.route) {
                popUpTo(NavigationItem.Register.route) {
                    inclusive = true
                }
            }
        }
        is BaseViewState.Loading -> LoadingView()
        is BaseViewState.Error -> BannerView()
        else -> {}
    }

在单击按钮时,我按如下方式调用viewModel:

registerViewModel.onTriggerEvent(
                    RegisterEvent.CreateUser(
                        usernameInputState.value.text,
                        emailInputState.value.text,
                        passwordInputState.value.text
                    )
                )

并且,在ViewModel中,我这样做我的请求:

override fun onTriggerEvent(eventType: RegisterEvent) {
        when (eventType) {
            is RegisterEvent.CreateUser -> createUser(eventType.username, eventType.email, eventType.password)
        }
    }

    private fun createUser(username: String, email: String, password: String) = safeLaunch {
        setState(BaseViewState.Loading)
        execute(createUser(CreateUser.Params(username, email, password))) {
            setState(BaseViewState.Data(RegisterViewState(it)))
        }
    }

我猜这应该是由重新组合引起的,因为我首先在When Scenario上放置了一个断点,它多次停在这里,但只在ViewModel上放置了一个断点.我怎么才能解决这个问题呢?

推荐答案

这个问题就在这里

is BaseViewState.Data -> {
        navController.navigate(NavigationItem.OnBoarding.route) {
            popUpTo(NavigationItem.Register.route) {
                 inclusive = true
            }
        }
}

每次你拨打navController.navigate,Navhost都会继续通过这个区块,执行一个无尽的循环.

我建议使用LaunchedEffectkey(如this)进行导航呼叫,

LaunchedEffect(key1 = "some key") {
     navController.navigate(…)
}

或者创建单独的 struct ,即,事件,其中它们作为SharedFlowemits 并通过Unit键控LaunchedEffect观察

LaunchedEffect(Unit) {
        viewModel.event.collectLatest {
            when (it) {
                is UiEvent.Navigate -> {
                    navController.navigate(…)
                }
            }
        }
    }

Android相关问答推荐

为什么使用. DeliverveAsState()时会出现空指针异常?

如何清除导航抽屉中以前 Select 的项目(Jetpack Compose)

在柯特林连续测量网速

如何使用 Wea​​r OS 上的运行状况服务模拟位置?

在 MVVM Jetpack Compose 上添加依赖项时出现重复类错误

如何绘制内边框?

Android Studio:按下前缀键:切换 Logcat 格式

在 react native 中设置 react-native-paper 组件的样式

在 Compose 中停止键盘将顶部应用栏推离屏幕

在 Kotlin 中设置 startActivity() 时类型不匹配

导航组件中预期的函数调用map(...)

如何从日期 Select 器计算年龄?

喷气背包组成影子奇怪的行为

如何对齐文本和图标可组合,以便即使在文本溢出后它们也能保持在一起?

Android Compose 创建抖动动画

Kotlin Compose forEach 中的负间距

线圈单元测试 - 如何做到这一点?

CenterAlignedTopAppBar 滚动行为:未为参数状态传递值

compose FontFamily 错误:必须初始化变量

如何满足设备内框架的无效 Wear OS 屏幕截图Wear OS 表盘策略违规?