> 文章列表 > Compose (8/N) - 隐式传参 CompositionLocal

Compose (8/N) - 隐式传参 CompositionLocal

Compose (8/N) - 隐式传参 CompositionLocal

一、概念

显示传参

局部变量,中间层或底层要使用通过函数形参层层传递,嵌套深耦合高不利于组合的复用。

隐式传参 全局变量,中间层或底层能直接获取,一处更改处处新值可通过局部改回去解决。

二、CompositionLocal

通常情况下,数据以参数形式向下传递给需要的组合,但对于广泛使用的常用数据(颜色形状...)会很麻烦。CompositionLocal 包装的全局变量,局部获取后更改值使用,改动的值出了该作用域失效,其它地方再次调用还是默认值。注意:变量名需要以“Local” 开头。

compositionLocalOf

值更改后,直接读取的地方会重组,局部修改的不会。
staticCompositionLocalOf 值更改后,所有引用的地方都会重组(不论直接读取还是局部修改),当值几乎不会被更改的时候使用性能更高,因为上面那个会追踪值的读取。
CompositionLocalProvider 提供作用域,修改的值只在该作用域内有效。
provides 用来修改值,可以是函数调用,推荐是中缀调用。
current 取出的值为最近外层所修改的值,外层所有嵌套不存在修改则为默认值。
val LocalUser = compositionLocalOf {    //编译器会提示变量名应该以“Local”为前缀User("张三")    //默认值,无默认值也可设置错误信息
}
@Composable
fun Show() {Column {//CompositionLocalProvider函数提供作用域,provides中缀表达式提供修改,current取出的值为CompositionLocalProvider(LocalUser provides User("李四")) {val newUser = LocalUser.current //这里取出的值为外部作用域修改过的Text(text = newUser.name)}val user = LocalUser.current    //这里取出的值外部作用域未作修改Text(text = user.name, fontWeight = FontWeight.Bold)val color = MaterialTheme.colors.primary    //这里取出的值是MaterialDesign提供的val context = LocalContext.current.resources.getString(R.string.app_name)    //获取上下文和资源}
}
//数据类定义值选择
data class MyColor(val red: String = "red",val blue: String = "blue"
)
data class MyFontSize(val h1: Int = 1,val h2: Int = 2
)
//单例提供分类选择
object MyDesign {val LocalMyColor = compositionLocalOf { MyColor() }val LocalMyFontSize = compositionLocalOf { MyFontSize() }
}
@Composable
fun Show() {//使用系统提供的val context = LocalContext.current.resources.getString(R.string.app_name)//使用自定义的val myColor = MyDesign.LocalMyColor.current.blue//修改自定义的CompositionLocalProvider(MyDesign.LocalMyColor provides MyColor(red = "light red")) {}}
}