如果它是 jetpack compose 中类的实例,如何通知状态更改

rus*_*aof 4 android android-jetpack android-jetpack-compose

我有这样的代码:

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}")
}
Run Code Online (Sandbox Code Playgroud)

当我单击 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) {

}
Run Code Online (Sandbox Code Playgroud)

Adr*_*n K 5

Compose 只能理解,如果您设置了State对象的值,它应该重新组合。在您的示例中myvalue.value++实际上只是 的缩写myvalue.value = myvalue.value.inc(),因此触发重组的是调用state.value设置器。
如果您只是改变状态所持有的对象的属性,则不会调用 setter 并且不会发生重组。

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

  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)
    }) {

    }
}
Run Code Online (Sandbox Code Playgroud)

这并不是很好读,但不需要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++ }) {

    }
}
Run Code Online (Sandbox Code Playgroud)