1.显示传参
package com.jmj.jetpackcomposecompositionlocalimport org.junit.Testimport org.junit.Assert.*/*** 显示传参*/
class ExplicitText {private fun Layout(){var color:String = "黑色";//参数需要通过层层传递,比较繁琐Text(color)Grid(color)Text(color)Text(color)}private fun Grid(color:String){println("other components in Grid")Text(color)}private fun Text(color:String){println("other components in Grid")println(color)}@Testfun test_explicit() {Layout()}
}
package com.jmj.jetpackcomposecompositionlocal.samplesimport androidx.compose.foundation.layout.Column
import androidx.compose.foundation.text.selection.LocalTextSelectionColors
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.DefaultAlpha
import androidx.compose.ui.platform.LocalAutofill
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.TextStyle@Composable
fun CompositionSample2(){MaterialTheme {Column {Text(text = "I AM A Cat")//如果要改变透明度的话 相当于用了一个全局变量,改变了全局变量的那个主题,然后改变了透明度然后又改回来CompositionLocalProvider(LocalTextStyle provides TextStyle(color = Color.Black.copy(alpha = 0.74f)) ){Text(text = "I AM A Dog")Text(text = "I AM A Rabbit")}CompositionLocalProvider(LocalTextStyle provides TextStyle(color = Color.Black.copy(alpha = 0.38f)) ){DescendantExample()}Text(text = "I AM A Rabbit")Text(text = "I AM A Rabbit")Text(text = "I AM A Rabbit")Text(text = "I AM A Rabbit")}}}@Composable
fun DescendantExample(){Text(text = "I AM A Mouse")
}
package com.jmj.jetpackcomposecompositionlocal.samplesimport androidx.compose.foundation.layout.Column
import androidx.compose.foundation.text.selection.LocalTextSelectionColors
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.DefaultAlpha
import androidx.compose.ui.platform.LocalAutofill
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.TextStyle
import com.jmj.jetpackcomposecompositionlocal.R@Composable
fun CompositionSample2(){MaterialTheme {Column {Text(text = "I AM A Cat")//如果要改变透明度的话 相当于用了一个全局变量,改变了全局变量的那个主题,然后改变了透明度然后又改回来CompositionLocalProvider(LocalTextStyle provides TextStyle(color = Color.Black.copy(alpha = 0.74f)) ){Text(text = "I AM A Dog")Text(text = "I AM A Rabbit")}CompositionLocalProvider(LocalTextStyle provides TextStyle(color = Color.Black.copy(alpha = 0.38f)) ){DescendantExample()}Text(text = "I AM A Rabbit")Text(text = "I AM A Rabbit")Text(text = "I AM A Rabbit")Text(text = "I AM A Rabbit")FruitText(3)}}}@Composable
fun DescendantExample(){Text(text = "I AM A Mouse")
}@Composable
fun FruitText(fruitSize:Int){//拿到当前 上下文资源val resources = LocalContext.current.resourcesval fruitText = resources.getQuantityString(R.plurals.fruit_title,fruitSize)Text(text = "${fruitSize} $fruitText")}
<resources><string name="app_name">JetpackComposeCompositionLocal</string><plurals name="fruit_title"><item quantity="one">fruit</item><item quantity="other">fruits</item></plurals>
</resources>
2.创建CompositionLocal
package com.jmj.newapp.samplesimport androidx.compose.foundation.background
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.CardElevation
import androidx.compose.runtime.Composable
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
// 数据类 默认重写了 tostring equals hashcode
data class Elevations(val card:Dp =0.dp)val LocalElevations = compositionLocalOf {// 里面给初始值Elevations()
}/*** 定义了一个单例模式的对象,里面有属性,相当于单例的属性*/
object CardElevation{val high:Elevationsget()=Elevations(card = 10.dp)val low:Elevationsget() = Elevations(card = 5.dp)
}@Composable
fun MyCard(//LocalElevations.current 就是 里面初始值的对象elevation: CardElevation = CardDefaults.elevatedCardElevation(defaultElevation = LocalElevations.current.card),backgroundColor: Color,content: @Composable ColumnScope.()-> Unit){Card(elevation = elevation,modifier = Modifier.size(200.dp),colors = CardDefaults.cardColors(containerColor = backgroundColor),content = content)
}
package com.jmj.newapp.samplesimport androidx.compose.foundation.layout.Column
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.TextStyle
import com.jmj.newapp.R@Composable
fun CompositionSample3(){Column {// 这是改变了全局的变量为 右边那个值,然后再域范围之外,又改回默认值,要么加了线程锁,要么就是每个线程一个作用域CompositionLocalProvider(LocalElevations provides CardElevation.high) {MyCard(backgroundColor = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.05f)) {}}MyCard(backgroundColor = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.05f)) {}}}
3.两种创建方式对比
package com.jmj.newapp.samplesimport android.nfc.Tag
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dpvar isStatic = true
var compositonLocalName = ""
val currentLocalColor = if (isStatic) {compositonLocalName = "StaticCompositionLocal 场景"staticCompositionLocalOf { Color.Black }
} else {compositonLocalName = "DynamicCompositionLocal 场景"compositionLocalOf { Color.Black }
}//重组标记,组件第一次加载是,recomposeFlag 为 Init
// 重组之前 (也就是第二次加载之前),将 recomposeFlag设置为 Recompose
var recomposeFlag = "Init"@Composable
fun CompositionSample4() {val (color, setColor) = remember {mutableStateOf(Color.Green)}Box(modifier = Modifier.fillMaxSize(),contentAlignment = Alignment.Center) {Column(horizontalAlignment = Alignment.CenterHorizontally) {Text(text = compositonLocalName)Spacer(modifier = Modifier.height(20.dp))//三个 TaggedBox组件 ,只有"Middle" 使用了CompositionLocalCompositionLocalProvider(currentLocalColor provides color) {TaggedBox(tag = "Wrapper: $recomposeFlag", size = 400.dp, background = Color.Red) {TaggedBox(tag = "Middle: $recomposeFlag",size = 300.dp,background = currentLocalColor.current) {TaggedBox(tag = "Inner: $recomposeFlag",size = 200.dp,background = Color.Yellow) {}}}}Spacer(modifier = Modifier.height(20.dp))// 点击按钮改变状态,将颜色设置为蓝色,观察3个TaggedBox组件是否重组Button(onClick = {setColor(Color.Blue)recomposeFlag = "Recompose"}) {Text(text = "Change Theme")}}}}@Composable
fun TaggedBox(tag: String,size: Dp,background: Color,content: @Composable () -> Unit = {}
) {Column(modifier = Modifier.size(size).background(background),horizontalAlignment = Alignment.CenterHorizontally) {Text(text = tag)Box(modifier = Modifier.fillMaxSize(),contentAlignment = Alignment.Center) {content()}}}