Android Jetpack Compose基础之CompositionLocal
在上篇文章末尾我们见到如下(代码1)
internal val LocalColorScheme = staticCompositionLocalOf { lightColorScheme() }
那么其中staticCompositionLocalOf又是什么,它有什么作用呢,首先它是创建CompositionLocal实例的两种方式中的一种。
什么是CompositonLocal
举例:有时候我们需要在Composable视图树中共享一些数据,如公共MaterialTheme配置,一种常见快速的方式,是通过显示参数传递的方式实现,但是如果参数很多,类似MaterialTheme它的参数非常多,那么每一个Composable的参数将会很难维护,假如它以如下方式传递公共颜色配置将会很麻烦
fun AScreen(
a: Color,
b: Color,
c: Color,
//...
d:Color
) {
BScreen(a,b,c,..d)
}
fun BScreen(
a: Color,
b: Color,
c: Color,
//...
d:Color
) {
}
而实际在我们实际的编码过程,发现如果我们要引用公共MaterialTheme配置颜色,只需要如下代码
MaterialTheme.colorScheme.surface即可实现引用自定的surface color值
val scrollState = rememberScrollState()
MyAPPTheme {
Surface(modifier = Modifier.background(MaterialTheme.colorScheme.surface)) {
Column(
modifier = Modifier
.fillMaxSize()
.verticalScroll(scrollState)
) {
MoreSample()
}
}
}
总的来说它属于Compsable树中实现公共参数方式:Compose提供了CompositionLocal用来实现在Composable树中共享数据,CompositionLocal是有层级规范的,它是被限定在以某个Compsable作为根节点的子树中,其默认是向下传递,并且允许在某个子节点中进行修改,从而使新值向下传递;
CompositonLocal 创建方式之staticCompositionLocalOf
使用方式
第一步:如(代码1)MaterialTheme内部创建了一个CompositonLocal对象
第二步:在Composable树中使用CompositionLocalProvider方法为CompositonLocal提供一个值,以MaterialTheme组件为例:
@Composable
fun MaterialTheme(
colorScheme: ColorScheme = MaterialTheme.colorScheme,
shapes: Shapes = MaterialTheme.shapes,
typography: Typography = MaterialTheme.typography,
content: @Composable () -> Unit
) {
val rippleIndication = androidx.compose.material.ripple.rememberRipple()
val selectionColors = rememberTextSelectionColors(colorScheme)
CompositionLocalProvider(
LocalColorScheme provides colorScheme,
LocalIndication provides rippleIndication,
androidx.compose.material.ripple.LocalRippleTheme provides MaterialRippleTheme,
LocalShapes provides shapes,
LocalTextSelectionColors provides selectionColors,
LocalTypography provides typography,
) {
ProvideTextStyle(value = typography.bodyLarge, content = content)
}
}
特点
使用staticCompositionLocalOf创建的CompositionLocal在状态发生改变的时候,CompositionLocalProvider中的content整体都会被重组,而不是限定在组合中读取内部current数值的Composable,所以只有当值确认一个值发生改变的可能性很低或者不会改变,使用它会提高性能
CompositonLocal 创建方式之compositionLocalOf
使用方式
@Composable
fun MyIconPreview2() {
val scrollState = rememberScrollState()
val currentLocalColor = compositionLocalOf { Color.Red }
var color by remember {
mutableStateOf(Color.Green)
}
MyAPPTheme {
Surface(modifier = Modifier.background(MaterialTheme.colorScheme.surface)) {
Column(
modifier = Modifier
.fillMaxSize()
.verticalScroll(scrollState)
) {
CompositionLocalProvider(
currentLocalColor provides color
) {
Text(
text = "compositionLocalOf",
modifier = Modifier.background(currentLocalColor.current)
)
}
}
}
}
}
特点
通过compositionLocalOf创建的CompistionLocal对象,如果它提供的值发生了改变,所有读取这个CompistionLocal current值的Composable都会发生改变
结束语
——note end——
but-----
留下疑问:compositionLocalOf创建的CompositionLocal是如何实现精准重组的呢?