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

发布于 2025-01-13 19:58:35 字数 1564 浏览 3 评论 0原文

我有这样的代码:

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 ,它就不起作用

如果我如何使 CustomText 重新组合myvalue 现在是 TestClass 的一个实例,并且它在下面的代码中发生了变化?

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

}

I've got code like this:

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

When I click CustomButton, CustomText recomposes and changes it's value (and it is ok), but if I replace myvalue with an object of some class it does'nt work

How do I make the CustomText recompose if myvalue is now an instance of TestClass and it changes in the code below?

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

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

墨洒年华 2025-01-20 19:58:35

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

    }
}

这不太好读,但不需要 TestClass 包含任何特定于 compose 的代码。

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

    }
}

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.

So you have 2 options to solve this:

  1. Make TestClass immutable and update the State with a new object
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)
    }) {

    }
}

This is not really nice to read but doesn't require TestClass to contain any compose-specific code.

  1. Make TestClass a state holder
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++ }) {

    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文