【问题标题】:State depends on another state , Android Compose状态依赖于另一个状态,Android Compose
【发布时间】:2021-04-20 22:35:47
【问题描述】:

我有一个可组合对象,它获取一个可变状态的整数!

整数是一个计时器值!像 0 一样每秒增加一次

我必须在可组合内做的是转换为可表示的字符串,比如 60 秒,我将显示 1 分钟

所以我这样做

    val timeString = remember {
       mutableStateOf("00:00")
    }

    val durationString  = if(duration!=0) {
    var secondTime = ((duration / 1000) % 60).toString()
    var minuteTime = ((((duration / 1000) / 60) % 60)).toString()
    if (secondTime.length == 1) {
        secondTime = "0$secondTime"
    }
    if (minuteTime.length == 1) {
        minuteTime = "0$minuteTime"
    }
    "$minuteTime:$secondTime"
}else{
    "00:00"
}


timeString.value = durationString

         Text(
            modifier = Modifier
                .weight(1f)
                .padding(horizontal = 16.dp),
            text = timeString.value,
            style = MaterialTheme.typography.h4
        )

但是文本没有更新,但是由于持续时间是一个可变状态,如果我直接使用它,文本会更新,所以我尝试了 LaunchedEffect 但它没有用我想知道我能做到这一点的最佳方法是什么撰写!

【问题讨论】:

  • 我还尝试创建另一个文本状态,并使用 launchEffect 更新文本状态值,但它不更新文本
  • remember(duration) { /* your if */} 包装你的 if 如果你想知道为什么我建议阅读记忆文档
  • 它不工作
  • 能否请您也提供您的状态创建/传递的代码
  • 你可以做一些不同的事情。用CountDownTimer? 定义ViewModel 并在您的可组合函数中使用类似:val secs = countTimeViewModel.seconds.observeAsState()

标签: android android-jetpack-compose


【解决方案1】:

就像我在评论中提到的那样,您需要扭曲每次在记忆中应该重新计算的内容,并将状态作为键传递(需要让 compose 知道它必须更新字符串)。

查看示例代码:

@Composable
fun outer() {
    val durationState = remember { mutableStateOf(600000) }
    LaunchedEffect(durationState) {
        // This not how you do a timer but close enough
        val step = 1000
        repeat(600000.div(step)) {
            durationState.value = durationState.value - step
            delay(step.toLong())
        }
    }
    questionComposable(durationState)
}

@Composable
fun questionComposable(durationState: MutableState<Int>) {
    val durationString = remember(durationState.value) {
        val duration = durationState.value
        if (duration != 0) {
            var secondTime = ((duration / 1000) % 60).toString()
            var minuteTime = ((((duration / 1000) / 60) % 60)).toString()
            if (secondTime.length == 1) {
                secondTime = "0$secondTime"
            }
            if (minuteTime.length == 1) {
                minuteTime = "0$minuteTime"
            }
            "$minuteTime:$secondTime"
        } else {
            "00:00"
        }

    }
    Text(
        text = durationString,
        style = MaterialTheme.typography.h4
    )
}

【讨论】:

  • 我从父可组合项中获取持续时间状态作为参数
  • 但它记住了,它唯一有效的时间是如果我直接输入它,持续时间状态的值也会使用 timerTask 更新,它每秒更新一次值
  • 当你像fun ex(durationState: MutableState&lt;Int&gt;)一样传递它时,这个代码也可以工作
  • 用完整的可组合物做一个要点或类似的东西我猜错误超出了提供的东西。
  • 不用生气,我只能猜测外面是什么,我更新了解决方案以更接近您的示例。此代码在 Compose Desktop 和 Android 上运行
猜你喜欢
  • 1970-01-01
  • 2022-06-23
  • 1970-01-01
  • 1970-01-01
  • 2021-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多