如何执行异步调用,我需要在 Jetpack Compose 中列组件的修改器参数的 onKeyEvent 中计算其结果?

问题描述 投票:0回答:1

问题很简单。我该怎么做,或者更好地说,我如何解决在 Jetpack Compose 中对用户输入调用异步函数的问题??

我的代码:

@Composable
fun board = Row() {
  var gameboard: MutableState<Array<IntArray>> = mutableStateOf(/* some value here */)
  Column(Modifier.onKeyEvent(myOnKeyPressedFunction(gameboard)){
    /* some stuff here */
  }
}

private fun myOnKeyPressedFunction(gameboard: MutableState<Array<IntArray>>): (KeyEvent) -> Boolean = {
  when (it.key) {
    Key.directionUp -> {
      val res: Boolean = asyncMethodUpdatingGameboard(gameboard)
      res //so the gameboard should be updated by the time it gets here and 
          //return true and then see the changes
    }
    else -> false
  }
}

private fun asyncMethodUpdatingGameboard(gameboard: MutableState<Array<IntArray>>) {
  val res: Boolean = /* perform some async calls here */
  res
}

问题是我不能使用 withContext 或 async/await,因为 onKeyEvent 没有挂起功能。 如果我使用 CoroutineScope.launch 调用异步任务,布尔值会在异步任务完成之前返回,因此面板不会重新渲染。

有什么想法吗?我应该尝试不同的架构吗?或者不同的修饰符?

android kotlin asynchronous async-await android-jetpack-compose
1个回答
0
投票

我不认为你可以在没有一些

Effect
CoroutineScope.launch
的情况下使用延迟功能,我能够实现同样的事情但不同的是在更新
gameboard
可变后重新渲染组成桌面项目状态。

首先,这是代码:

@Composable
fun Board() {
    val gameboard: MutableState<Array<IntArray>> = mutableStateOf(arrayOf(intArrayOf(1,2)))
    val scope = rememberCoroutineScope()
    Row {
        Column {
            Text("Value is ${gameboard.value}")
        }
        TextField("", {}, modifier = Modifier.onKeyEvent {
            when (it.key) {
                Key.DirectionUp -> {
                    scope.launch{
                        asyncMethodUpdatingGameboard(gameboard)
                    }
                    true
                }
                else -> false
            }
        })
    }
}

private suspend fun asyncMethodUpdatingGameboard(gameboard: MutableState<Array<IntArray>>) : Boolean {
    delay(1000)
    gameboard.value = arrayOf(intArrayOf(1,2,3))
    return false
}

结果如下:

我正在使用我的键盘向上箭头(我没有作弊😂)

这是我所做的:

  • 我创建并记住了我将在其中运行我的 asyncTask 的协程作用域,它将在重组后继续存在并被记住。
  • 我不认为你可以在普通的行或列上调用
    onKeyEvent
    ;我能够在普通的 TextField 上获得事件
  • 我添加了一个文本来观察游戏板的价值。
  • 最后,我更新了
    asyncMethodUpdatingGameboard
    中的那个游戏板,在用
    suspend
    关键字暂停它之后;如您所见,我使用了 1 秒的延迟。
  • 1秒后文字正常更新

我希望你可以使用示例代码在你的代码中尝试这个想法。

© www.soinside.com 2019 - 2024. All rights reserved.