You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Compose中mutableStateOf自定义类修改属性不触发重组问题

问题原因

你的代码没有触发重组的核心原因是对Compose mutableStateOf的监听机制理解有误:

  • mutableStateOf 只会追踪它持有对象的引用变更,不会自动监听所持对象内部可变属性的修改
  • 你的ValidationButtonModel所有属性都定义为var可变类型,点击事件中你只是修改了对象内部的属性值,State持有的对象引用从头到尾没有发生变化,Compose完全检测不到状态变更,自然不会触发重组
  • 你自定义的Saver只负责配置变更/进程销毁时的状态保存与恢复,和重组触发逻辑完全无关,加Saver解决不了这个问题。另外你写的Saver本身还有索引越界bug:save时只存入了6个元素(索引范围0~5),restore时却取it[6],实际运行到状态恢复逻辑时会直接崩溃。
解决方案

推荐优先使用官方倡导的不可变状态方案,稳定性最高、维护成本最低:

  1. 把ValidationButtonModel的所有属性从var改为val不可变类型,依靠data class的copy()方法实现状态更新:
import android.os.Parcelable
import kotlinx.parcelize.Parcelize

@Parcelize
data class ValidationButtonModel(
    val title: Int,
    val contentDescription: Int,
    val rfidReadingStarted: Boolean,
    val progression: Float,
    val read: Int,
    val expected: Int,
) : Parcelable
  1. 修改状态时,创建新的对象实例赋值给State,触发引用变更通知:
Button(
    onClick = {
        val currentState = validationButtonModelState
        if (currentState.progression < 1.0f) {
            // 赋值新对象,State检测到引用变化后自动触发重组
            validationButtonModelState = currentState.copy(
                rfidReadingStarted = true,
                progression = currentState.progression + 0.1f,
                read = currentState.read + 1
            )
        }
    }
) {
    Text("INCREMENT")
}
  1. 之前的自定义Saver可以直接删掉,@Parcelize已经能配合rememberSaveable自动完成状态持久化,不需要额外实现Saver逻辑。

如果你一定要保留可变对象的写法,就需要把类内部每个需要触发重组的属性都委托给mutableStateOf,让Compose能追踪到属性变化,但这种方案需要自行实现状态保存逻辑,无法直接使用@Parcelize,维护成本更高,非必要不推荐。

内容的提问来源于stack exchange,提问作者Z3nk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 23:12:33