android JetpackCompose如何检测变量的变化以进行重组

ifmq2ha2  于 2023-05-15  发布在  Android
关注(0)|答案(2)|浏览(206)

我正在做一个谷歌Codelab,并有以下代码(当按下按钮时可绘制的变化):

@Composable
fun DiceWithButtonAndImage(modifier: Modifier = Modifier) {
    var result by remember { mutableStateOf(1) }
    val imageResource = when (result) {
        1 -> R.drawable.dice_1
        2 -> R.drawable.dice_2
        3 -> R.drawable.dice_3
        4 -> R.drawable.dice_4
        5 -> R.drawable.dice_5
        else -> R.drawable.dice_6
    }

    Column(
        modifier = modifier,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Image(painter = painterResource(imageResource), contentDescription = result.toString())

        Button(onClick = { result = (1..6).random() }) {
            Text(text = stringResource(R.string.roll_text))
        }
    }
}

Compose如何知道result在触发重组时发生了更改?它是否通过Imagepainter参数检测到这一点?或者通过remembermutableStateOf()

h5qlskok

h5qlskok1#

答案在文档中:
mutableStateOf创建一个observableMutableState<T>,它是一个与compose运行时集成的observable类型。对此值的任何更改都会计划重新组合读取该值的任何可组合函数。
在您的示例中,当您单击按钮时,result会发生变化。imageResource读取该值,并触发最近作用域中的重组。由于Column是一个内联函数(这意味着Column没有自己的重组作用域),因此Column的内容被重组。
您可以使用此功能直观地检查它:

fun randomColor() = Color(
    Random.nextInt(256),
    Random.nextInt(256),
    Random.nextInt(256),
    alpha = 255
)

ButtonColumn的背景色应用相同的函数:

Column(
        modifier = Modifier.background(getRandomColor()),
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Image(
            modifier = Modifier.background(getRandomColor()),
            painter = painterResource(R.drawable.ic_xxx), contentDescription = result.toString())

        Button(onClick = { result = (1..6).random() },
                colors= ButtonDefaults.buttonColors(containerColor = getRandomColor()),) {
            Text(text = "Button")
        }
    }

请注意,在本例中,Image使用静态资源,而不是imageResource

wz3gfoph

wz3gfoph2#

很难简单地回答这个问题,用一个简单的形式-编写使用快照系统来检测更改。它使用观察者模式来观察状态的变化。依赖于状态寄存器的代码部分会更改侦听器,当值更改时,所有已注册的侦听器都会收到通知。
因此,在您的示例中,mutableStateOf(1)自动在Composer中创建侦听器,并且DiceWithButtonAndImage函数在每次状态更改时都会收到通知。

相关问题