我有这样的代码:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            TestsTheme {
                var myvalue = remember{ mutableStateOf(4)}
                Row() {
                    CustomText(myvalue = myvalue)
                    CustomButton(myvalue = myvalue)
                }
            }
        }
    }
}

@Composable
fun CustomButton(myvalue: MutableState<Int>) {
    Button(onClick = {myvalue.value++}) {

    }
}

@Composable
fun CustomText(myvalue: MutableState<Int>) {
    Text("${myvalue.value}")
}

当我点击CustomButton时,CustomText会重新组合并更改它的值(这是可以的),但如果我用某个类的对象替换myvalue,它就不起作用了

如果myvalue现在是TestClass的一个实例,并且它在下面的代码中发生了更改,那么如何重新组合CustomText?

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            TestsTheme {
                var myvalue = remember{ mutableStateOf(TestClass(4))}
                Row() {
                    CustomText(myvalue = myvalue)
                    CustomButton(myvalue = myvalue)
                }
            }
        }
    }
}

@Composable
fun CustomButton(myvalue: MutableState<TestClass>) {
    Button(onClick = {myvalue.value.a++}) {

    }
}

@Composable
fun CustomText(myvalue: MutableState<TestClass>) {
    Text("${myvalue.value.a}")
}

data class TestClass(var a: Int) {

}

推荐答案

Compose can only understand that it should recompose if you set the value of a State object. In your example myvalue.value++ is really just short for myvalue.value = myvalue.value.inc(), so what triggers the recomposition is calling the state.value setter.
If you just mutate a property of the object held by a state, you are not calling the setter and no recomposition happens.

所以你有两个 Select 来解决这个问题:

  1. 使TestClass不可变,并用新对象更新State
data class TestClass(val a: Int) { // << changed var to val

}

@Composable
fun CustomButton(myvalue: MutableState<TestClass>) {
    Button(onClick = {
        val current = myvalue.value
        myvalue.value = current.copy(a = current.a + 1)
    }) {

    }
}

这不是很好读,但不需要TestClass来包含任何特定于编写的代码.

  1. 使TestClass人成为国家所有人
class TestClass(a: Int) { 
    var a by mutableStateOf(a)
}


@Composable
fun Parent(){
    val myvalue = remember{ TestClass(4) } // no mutableStateOf, state is managed inside the object
    CustomButton(myvalue = myvalue)
}
@Composable
fun CustomButton(myvalue: TestClass) {
    Button(onClick = { myvalue.a++ }) {

    }
}

Android相关问答推荐

道查询注释部分房间表名称

当X为lambda函数时,如何避免Android Studio错误检测参数X未使用?

图像在Android Studio中显示,但不在设备中显示

约束布局:垂直链中的视图应将内容包裹到空间的1/3

对支持哪些数据存储区方法感到困惑

try 用Jetpack Compose理解视图模型和导航

在Jetpack Compose中,我可以配置动画以恒定的速度而不是恒定的时间运行吗?

Dispatchers中的Kotlin协同程序.Main没有';t块主螺纹

使用lazyColumn迁移paging3的旧代码

升级到 Jetpack Compose 物料 list 2023.08.00 需要我将 targetSdk 更改为 34

使用 Jetpack Compose 在 Android TV 上启用系统声音

减少Compose中可滚动选项卡之间的间距

Jetpack Compose 中的用户在线指示器

在 jetpack compose 中交替使用 View.INVISIBLE

Jetpack Compose 部分或开放侧边框

在android studio中使用wifi配对设备的问题

TextField 溢出和软包装不适用于 Compose 约束布局

新安装 Expo Go 的 android 设备上的 sdk 46.0.0 (@snack/sdk.46.0.0) 出错

设备文件资源管理器-ROOM 数据库中的数据库文件夹为空

MVVM - 这个逻辑的最佳层是什么?