一、概念

| 显式传参 |
局部变量,中间层或底层要使用通过函数形参层层传递,嵌套深耦合高不利于组合的复用。 |
| 隐式传参 | 全局变量,中间层或底层能直接获取,一处更改处处新值。 |
二、CompositionLocal
通常情况下,数据通过形参传递给函数,可组合函数是层层嵌套的形式,但对于广泛使用的常用数据(例如颜色形状...)层层往下传递会很麻烦,而使用全局变量的话,当需要对该值修改后使用,一处修改会导致所有调用处都是新值,即便赋值给局部变量再使用,更底层函数想使用该局部变量,不是再层层传递下去就是又需要用局部变量去接收,还做不到层层引用相同的变量名(污染中间函数)。
使用 CompositionLocal 包装的全局变量,对于值的修改既可以全局生效,也可以只在 CompositionLocalProvider 提供的作用域内局部有效(函数穿透功能:在作用域内就能生效,无关作用域内的函数层级),出了该作用域失效,不会影响其它调用处。注意:变量名需要以“local” 开头,top-level需要以“Local”开头。
|
compositionLocalOf() |
public fun <T> compositionLocalOf( 值更改后,只有直接读取该值的组合项会重组(CompositionLocalProvider提供的作用域中,读取的是修改后的,并未直接读取,不会重组)。 |
| staticCompositionLocalOf() |
public fun <T> staticCompositionLocalOf( defaultFactory: () -> T ): ProvidableCompositionLocal<T> 值更改后,所有引用的地方都会重组(不管是直接读取该值的组合项,还是CompositionLocalProvider提供的作用域),当值几乎不会被更改的时候使用性能更高,因为上面那个会追踪值的读取。 |
| CompositionLocalProvider | 提供作用域,修改的值只在该作用域内有效。 |
| provides | 用来修改值,可以是函数调用,推荐是中缀调用。 |
| current | 取出的值为最近外层所修改的值,外层所有嵌套不存在修改则为默认值。 |
//编译器会提示变量名应该以“Local”为前缀
//不想提供或无法提供有意义的默认值,可以直接抛异常。
val LocalUser = compositionLocalOf { User("张三") }
//val LocalUser = compositionLocalOf { error("LocalUser没有提供值!") }
@Composable
fun Show() {
Column {
//CompositionLocalProvider函数提供作用域,provides中缀表达式提供修改,current取出当前值
CompositionLocalProvider(LocalUser provides User("李四")) {
val newUser = LocalUser.current //这里取出的值是修改过的“李四”
}
val user = LocalUser.current //这里取出的值是未修改过的“张三”
val color = MaterialTheme.colors.primary //这里取出的值是MaterialDesign提供的
val context = LocalContext.current.resources.getString(R.string.app_name) //获取上下文和资源
val app = LocalContext.current.applicationContext as MyApplication //获取自定义的 Application
}
}
CompositionLocal提供了一种在JetpackCompose中管理全局状态的方式,它允许值在组件树中局部生效,避免了传统全局变量的副作用。通过CompositionLocal,开发者可以修改值并控制其影响范围,提高代码的可复用性和组合性。CompositionLocalOf用于创建实例,current属性用于获取值,而CompositionLocalProvider则用于提供作用域内的新值。
1449

被折叠的 条评论
为什么被折叠?



