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")) {

        }
    }
}

猜你喜欢

转载自blog.csdn.net/HugMua/article/details/130049635
今日推荐