Compse之重组

248 阅读1分钟

1.什么是重组

重组,重新组合,重新绘制UI,既重新调用了可组合函数

@Composable
fun Step1() {
    Log.d("lyl", "Step1")
    Checkbox(checked = false, onCheckedChange = {
        Log.d("lyl", "Checkbox $it")
    })
}

点击CheckBox后,可组合函数Step1不会再次执行,即没有触发重组,那么谁会触发重组呢?

  1. 由谁触发重组

由State#value触发

可以使用mutableStateOf()方法构造一个State

@StateFactoryMarker
fun <T> mutableStateOf(
	value: T,
	policy: SnapshotMutationPolicy<T> = structuralEqualityPolicy()
): MutableState<T> = createSnapshotMutableState(value, policy)


@Stable
interface MutableState<T> : State<T> {
	override var value: T
}

因为State#value的变化是可以被Compose框架感知的,State#value变化后,会触发重组

@SuppressLint("UnrememberedMutableState")
@Composable
fun Step2() {
    val checkState = mutableStateOf(false)
    Log.d("lyl", "Step2 ${checkState.value}")
    Checkbox(checked = checkState.value, onCheckedChange = {
        checkState.value = it
        Log.d("lyl", "${checkState.value}, $it")
    })
}

此时的checkState就是一个State了,也就是所谓的“状态”,我们可以通过.value访问它的值

通过log可以看出State#value变化,确实触发了重组,即重新调用了可组合函数

但是重组后,checkState的值又被重置了。日志如下:

image.png

  1. 触发重组后,怎么能够访问到之前已经改变了的值,即如何让状态能够跨越重组而持久存在

使用remember

@Composable
fun Step3() {
    var checkState by remember {
        mutableStateOf(false)
    }

    Log.d("lyl", "Step3 $checkState")
    Checkbox(checked = checkState, onCheckedChange = {
        checkState = it
        Log.d("lyl", "$checkState, $it")
    })
}

Compose会在初始组合期间将由remember计算的值存储在组合内存中,并在重组,即再次调用可组合函数Step3时,返回存储的值。日志如下:

image.png

和mutableStateOf类似的还有derivedStateOf

和remember类似的还有rememberSavable