android 如何执行一个异步调用,其结果需要在Jetpack Compose中列组件的修饰符参数的onKeyEvent中计算?

pdsfdshx  于 2023-03-16  发布在  Android
关注(0)|答案(1)|浏览(160)

问题很简单,我该怎么做,或者更好地说,我该怎么解决在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调用异步任务,布尔值在异步任务完成之前返回,因此电路板不会重新渲染。
有什么想法吗?我应该尝试不同的架构吗?或者不同的修改器?

rsl1atfo

rsl1atfo1#

我不认为你可以使用延迟功能没有一些EffectCoroutineScope.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
}
以下是结果:

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

以下是我的做法:
  • 我创建并记住了协同程序作用域,我将在该作用域中运行我的asyncTask,它将在重新组合后仍然存在并被记住。
  • 我不认为你可以在一个普通的行或列上调用onKeyEvent;我可以在普通文本域上获取事件
  • 我添加了一个文本来观察游戏板的价值。
  • 最后,我在asyncMethodUpdatingGameboard中更新了那个游戏板,用suspend关键字使它挂起;如你所见,我使用了1秒的延迟。
  • 文本通常在1秒后更新。

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

相关问题