开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第8天,点击查看活动详情
前两天实在太忙了,没有来得及更新,今天周五了,可以慢慢更新~~
今天就来讲讲Compose中CompositionLocal的使用,正好这两天项目中也在用,觉得挺好用的,解决了一些难题,通过这篇文章的分享也想加深一下自己的理解。
首先了解CompositionLocal如何构建,CompositionLocal有两种构建方式如下:
val localTitle = compositionLocalOf { "Video" }
val localColor = staticCompositionLocalOf { Color.Red }
compositionLocalOf支持局部修改,而staticCompositionLocalOf是全局的不支持局部的修改,compositionLocalOf的使用:
Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colors.background) {
Column() {
Greeting("Android")
CompositionLocalProvider(localTitle provides "Audio") {
Text(text = localTitle.current)
}
CompositionLocalProvider(localTitle provides "Hello") {
Text(text = localTitle.current)
}
}
}
这里使用CompositionLocalProvider来用localTitle,那下面的两个text分别显示“Audio”和“Hello”。这个变量的作用域就是CompositionLocalProvider括号里面的部分。这个情况就适合局部变化的变量,下面再看看staticCompositionLocalOf创建的local变量的使用:
Text(text = localTitle.current, color = localColor.current)
这个直接使用就可以了,但是这两种方式有什么差别呢?我们尝试使用CompositionLocalProvider局部改变一下localColor的值试试:
Text(text = localTitle.current, color = localColor.current)
CompositionLocalProvider(localColor provides Color.Green) {
Text(text = localTitle.current,color = localColor.current)
}
Text(text = localTitle.current,color = localColor.current)
最后发现这个颜色是:红,绿,红,感觉和compositionLocalOf的效果是一样的。最后去看了官网的解释,其实对于compositionLocalOf和staticCompositionLocalOf改变当前值的方式都是这样的,那么这两个到底有什么不同呢,看一下官网的解释:
compositionLocalOf:在重组期间更改提供的值只会使读取其current值的内容无效。staticCompositionLocalOf:与compositionLocalOf不同,Compose 不会跟踪staticCompositionLocalOf的读取。更改该值会导致提供CompositionLocal的整个contentlambda 被重组,而不仅仅是在组合中读取current值的位置。
按照官网的办法我都两种类型进行了验证,但是我发现这两种方式都只会重组读取的位置,staticCompositionLocalOf也没有进行全局的recomposable,下面是我的验证发送 我们先来验证compositionLocalOf,我们先来看定义:
val titleState = mutableStateOf("video")
val localTitle = compositionLocalOf { titleState }
然后再写两个方法:
@Composable
fun Title1(){
Log.i("test","Title1")
Text(text = localTitle.current.value)
}
@Composable
fun Title2(){
Log.i("test","Title2")
Text(text = "title2")
}
方法1使用了localTitle的值,而方法而没有使用,然后去使用这两个方法:
CompositionLocalProvider(localTitle provides titleState) {
Title1()
Title2()
}
LaunchedEffect(key1 = Unit ){
delay(10000)
titleState.value = "hello"
}
后面的LaunchedEffect在10s后改变titleState的值,我们看看打印情况:
2022-12-02 21:09:21.943 I/test: Title1
2022-12-02 21:09:21.944 I/test: Title2
2022-12-02 21:09:32.016 I/test: Title1
现在看到在10秒钟后方法1发生了重组,而方法二没有。将localTitle改成staticCompositionLocalOf发现最后的情况是一样的,不知道是不是我的验证方式有问题,这个还有待于进一步的验证。