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是如何实现精准重组的呢?

  • 19
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值