Compose 基础 - 层级上下文(覆盖常量局部生效) CompositionLocal

发布时间:2026/7/24 22:58:06
Compose 基础 - 层级上下文(覆盖常量局部生效) CompositionLocal 一、概念1.1 函数嵌套的传参问题Compose 是函数层层嵌套的形式。对于全局广泛使用的常用数据如颜色不应该层层传递下去而是在每一层都能直接获取但全局变量存在修改隐患。显式传参通过参数列表传递。外层数据想要传递给更底层使用得通过参数列表层层传递污染中间函数还会导致调用链边长嵌套深耦合高不利于复用。隐式传参读取全局变量。虽然更底层能直接获取但一处更改所有调用处都被改内部隐式依赖了外部导致难测试还存在重组多线程引起的并发问题。数据变化后想要传递给更底层使用又回到了显示传参的问题。1.2 使用效果创建 CompositionLocal 时设置的默认值无法后期修改但可以被 CompositionLocalProvider 覆盖后在局部生效修改这个用来覆盖的值只会影响该 CompositionLocalProvider 范围内。通过定义全局参数 Localxxx可以在函数嵌套结构中直接获取值而无需层层传递。使用 CompositionLocalProvider 可对该常量值进行覆盖在它提供的局部作用域内无论函数层级依旧是通过全局参数名称 Localxxx 获取值但获取的是覆盖后的值出了作用域失效再获取就是默认值。起到函数穿透和层级上下文的作用。若存在 CompositionLocalProvider 嵌套内层获取的是内层覆盖的值出了内层再获取就是外层覆盖的值出了最外层再获取就是默认值若修改这个用来覆盖的值若覆盖的是 compositionLocalOf() 常量只会引起 CompositionLocalProvider 作用域内读取该常量的组件重组。若覆盖的是 staticCompositionLocalOf() 常量则会引起 CompositionLocalProvider 作用域内全部重组。二、使用命名方式需要以“local” 开头top-level需要以“Local”开头。compositionLocalOf()叫它动态Localpublic fun T compositionLocalOf(policy: SnapshotMutationPolicyT structuralEqualityPolicy(),defaultFactory: () - T,): ProvidableCompositionLocalTstaticCompositionLocalOf()叫它静态Localpublic fun T staticCompositionLocalOf(defaultFactory: () - T): ProvidableCompositionLocalT当提供的默认值几乎不会被更改的时候使用性能更高因为上面那个会追踪值的读取。CompositionLocalProviderpublic fun CompositionLocalProvider(value: ProvidedValue*,content: Composable () - Unit)提供作用域提供的值只在该作用域内有效。providespublic infix fun provides(value: T): ProvidedValueT用来提供值可以是函数调用推荐是中缀调用。currentpublic inline val current: T取出的值为最近的外层CompositionLocalProvider所提供的值若外层没有CompositionLocalProvider则为默认值。//编译器会提示变量名应该以“Local”为前缀 val LocalUser compositionLocalOf { User(张三) } //不想提供或无法提供有意义的默认值可以直接抛异常。 //val LocalUser compositionLocalOf { error(LocalUser没有提供值) } Composable fun Demo() { var user by remember { mutableStateOf(User(李四)) } //改变这个变量会触发重组 Column { CompositionLocalProvider( LocalUser provides user //用变量值对常量进行覆盖并在局部作用域内生效 ) { val user1 LocalUser.current //外层作用域内读取的值是“李四” //嵌套一层 CompositionLocalProvider( LocalUser provides User(王五) //用非变量覆盖不需要变更控制重组的话 ) { val user2 LocalUser.current //嵌套作用域内读取的值是“王五” } val user3 LocalUser.current //出了嵌套作用域回到外层作用域读取的值是“李四” } val user4 LocalUser.current //出了外层作用域读取的值是默认的“张三” } }三、系统提供的上下文LocalContext配置LocalConfiguration密度LocalDensity震动LocalHapticFeedback