Android compose Icon重组问题

Rus*_*nko 2 android kotlin android-jetpack-compose

我创建了一个仅显示一个图标、两个文本和两个按钮的应用程序。单击任何按钮时,相应的文本都会更新,因为它取决于我的函数中传递的值。但与文本一起,每次图标重新组合时,它甚至不依赖于任何值。

data class TestUIState(
    val counterA: Int = 0,
    val counterB: Int = 0,
)

@HiltViewModel
class TestViewModel @Inject constructor() : ViewModel() {
    val uiFlow = MutableStateFlow(TestUIState())
    val data: TestUIState
        get() = uiFlow.value


    fun increaseCounterA() {
        uiFlow.value = data.copy(counterA = data.counterA + 1)
    }

    fun increaseCounterB() {
        uiFlow.value = data.copy(counterB = data.counterB + 1)
    }
}

@Composable
fun TestCompose(
    uiValueState: State<TestUIState>,
    increaseCounterA: () -> Unit,
    increaseCounterB: () -> Unit,
) {
    Column(modifier = Modifier.fillMaxSize()) {
        Icon(
            painter = painterResource(id = R.drawable.ic_google),
            contentDescription = "",
        )
        Text(text = "CounterA: ${uiValueState.value.counterA}", color = Color.White)
        Text(text = "Counter B: ${uiValueState.value.counterB}", color = Color.White)
        Button(onClick = increaseCounterA) {
            Text(text = "Increase counter A")
        }
        Button(onClick = increaseCounterB) {
            Text(text = "Increase counter B")
        }
    }
}
setContent {
                val testViewModel: TestViewModel = hiltViewModel()
                TestCompose(
                    uiValueState = testViewModel.uiFlow.collectAsStateWithLifecycle(),
                    increaseCounterA = testViewModel::increaseCounterA,
                    increaseCounterB = testViewModel::increaseCounterB
                )
}
Run Code Online (Sandbox Code Playgroud)

当我按下更新计数器 A 按钮时,我在布局检查器中看到下一个: 重组计数

然后,当我按下更新计数器 B 按钮时,图标再次重新组合。 重组计数 2

我只是无法理解为什么每次与该图标无关的某些值发生变化时,静态图像都会重新组合。或者这个元素的行为是否符合预期?我不知道。请帮助我理解这个问题。

Thr*_*ian 5

当在范围内读取 a 时,State不可跳过的可组合项会被重组,即使它们的输入没有改变。

读取任一Text可组合项中的 state.value 都会触发TestCompose范围重组。作用域是返回 Unit 的非内联函数。布局检查器显示具有内联的可组合项,这不是范围,正如您在 Column 中看到的那样。您可以在此答案和链接的文章中查看范围重组。

Jetpack Compose 智能重组

当任一文本函数输入随相应的Button变化计数器 A 或 B 变化时,它们都不会在每次重组时进行重组。

但是,参数Icon不稳定Painter,因此即使您传递相同的参数,Painter它也会在TestCompose范围内的每次重组时进行重组。

如果您创建以画家作为参数的函数

@Composable
private fun MyIcon(
    painter:Painter
) {

    Icon(
        painter = painter,
        contentDescription = "",
    )
}
Run Code Online (Sandbox Code Playgroud)

它会记录

restartable scheme("[androidx.compose.ui.UiComposable]") fun MyIcon(
  unstable painter: Painter
)
Run Code Online (Sandbox Code Playgroud)

如果您想了解有关稳定性的更多信息,可以查看Ben Trengrove 的这篇文章。

  • 本文介绍了如何记录函数和类型。https://medium.com/androiddevelopers/jetpack-compose-stability-explained-79c10db270c8 (2认同)
  • 是的,但再次使用注释和编写自定义函数来仅显示简单的图标对我来说看起来像是解决方法,我们只是修复图标实现中的错误。恕我直言 (2认同)