小编And*_*er2的帖子

为什么在使用 Jetpack 导航和 Compose 时视图不断闪烁?

我有一个登录屏幕,当登录成功并且视图模型更新可变状态变量时,我的期望是调用一个新的可组合函数来显示新屏幕,并删除登录屏幕。问题是,当Screen.AccountsScreen显示新屏幕(又名)时,其内容不断闪烁/重绘,并且登录表单也会发生同样的情况,而该登录表单永远不会被破坏(我知道这一点是因为日志消息“Recomponing...”被无休止地打印) 。我认为发生这种情况是因为isLoginSuccessful状态始终为真。看来我需要一个只能消耗一次的事件,这是正确的吗?如果是这样,我该怎么做?

LoginViewModel.kt

@HiltViewModel
class LoginViewModel @Inject constructor() : ViewModel() {

  var isLoginSuccessful by mutableStateOf(false)
  var errorMessage by mutableStateOf("")
  
  fun onLoginClick(email: String, password:String) {
    errorMessage = ""
    if (credentialsValid(email, password)) {
      isLoginSuccessful = true
    } else {
      errorMessage = "Email or password invalid"
      isLoginSuccessful = false
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

LoginScreen.kt

@Composable
fun loginScreen(
  navController: NavController,
  viewModel: LoginViewModel = hiltViewModel()
) {
  println("Recomponing...")
  // Here gos the code for the login form
  
  if (viewModel.isLoginSuccessful) {
    navController.navigate(Screen.AccountsScreen.route) { …
Run Code Online (Sandbox Code Playgroud)

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

12
推荐指数
1
解决办法
5933
查看次数

如何使用 Kotlin Flow 从异步回调中发出数据?

我开始学习 Kotlin Flow 和 Coroutines,但我不知道如何使下面的代码起作用。我究竟做错了什么?

interface MessagesListener {
    fun onNewMessageReceived(message: String)
}

fun messages(): Flow<String> = flow {

    val messagesListener = object : MessagesListener {
        override fun onNewMessageReceived(message: String) {

            // The line below generates the error 'Suspension functions can be called only within coroutine body'

            emit(message)
        }
    }

    val messagesPublisher = MessagesPublisher(messagesListener)
    messagesPublisher.connect()
}
Run Code Online (Sandbox Code Playgroud)

android kotlin kotlin-coroutines kotlin-coroutines-flow

6
推荐指数
2
解决办法
1846
查看次数

如何将 kotlin 中的挂起函数和流程的结果结合起来?

伙计们想象我有这两个数据源:

val flowA: Flow<String>
suspend fun funB(): Int
Run Code Online (Sandbox Code Playgroud)

如何将两者的结果合并到一个流程中(比方说Flow<Pair<String, Int>>)?

下面的方法怎么样?有没有更好的办法?

combine(
  flowA,
  flow {emit(funB())}
) { a, b ->
  ...
}
Run Code Online (Sandbox Code Playgroud)

suspend reactive-programming kotlin kotlin-flow

3
推荐指数
1
解决办法
1235
查看次数