介绍与使用
介绍
CompositionLocal
是通过组合隐式向下传递数据的工具
通俗一点的讲法就是:在任意一个使用@Compose
注解声明的函数, 都能访问到声明的CompositionLocal声明的变量。有点类似于静态变量,全局任何一个类,任何一个方法都能访问这个全局的静态变量。
使用示例
声明CompositionLocal类型的变量
// LocalElevations.kt file
data class Elevations(val card: Dp = 0.dp, val default: Dp = 0.dp)
// Define a CompositionLocal global object with a default
// This instance can be accessed by all composables in the app
val LocalElevations = compositionLocalOf { Elevations() }
上面声明了一个Elevation实体类,使用compositionLocalOf{} 包裹一下Elecations对象。这就完成了CompositionLocal的声明,是不是很简单。
使用上面声明的CompositionLocal变量
// MyActivity.kt file
class MyActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
// Calculate elevations based on the system theme
val elevations = Elevations(card = 0.dp, default = 0.dp)
// Bind elevation as the value for LocalElevations
CompositionLocalProvider(LocalElevations provides elevations) {
// ... Content goes here ...
Text("Hello World!!")
}
}
}
}
@Compose
fun Text(str: String) {
// 通过LocalElevations.current可以获取到声明的变量值
val alpha = LocalElevations.current.card
Box {
Text(
text = str,
modifier = Modifier.alpha(alpha)
)
}
}
通过CompositionLocalProvide方法,定义一个CompositionLocal类型变量。这个变量的作用域是UI树
。UI树意思就是通过compose函数定义的UI组合构成了一颗完整的UI树
。在这个UI树中的任意地方都可以访问到声明的LocalElevations, 比通过函数参数输入的方式,这种隐式输入的方式给开发者带来更高的开发效率
。
特性介绍
CompositiongLocal类型的变量除了能够在Compose的UI树中隐式注入
和快捷读取
外,还能局部更改compositionLocal的值,并且只影响部分UI树的子节点读取该值。以外的UI树子节点读取值不受影响。
@Composable
fun CompositionLocalExample() {
MaterialTheme { // MaterialTheme sets ContentAlpha.high as default
Column {
// 默认值为0
//读取到的值为0
Text("Uses MaterialTheme's provided alpha")
// 更改值为1
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
//读取值是1
Text("Medium value provided for LocalContentAlpha")
Text("This Text also uses the medium value")
// 更改值为2
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.disabled) {
// 读取值为2
DescendantExample()
}
}
// 读取到的值为0
Text("Uses MaterialTheme's provided alpha")
}
}
}
@Composable
fun DescendantExample() {
// CompositionLocalProviders also work across composable functions
Text("This Text uses the disabled alpha now")
}
CompositionLocalProvider
用于为一部分的组合提供不同的值,不影响全局数据
使用注意事项
CompositionLocal使得可组合项的行为更难推断。
- 在创建隐式依赖项时,使用这些依赖项的可组合项的调用方需要确保为每个
CompositionLocal
提供一个值。 - 此外,该依赖项可能没有明确的可信来源,因为它可能会在组合中的任何部分发生改变。因此,在出现问题时调试应用可能更具有挑战性因为需要向上查看组合,了解提供
current
值的位置
CompositionLocal
应具有合适的默认值