如何在jetpack compose中将contentColor应用于表面中的孩子

Posted

技术标签:

【中文标题】如何在jetpack compose中将contentColor应用于表面中的孩子【英文标题】:How contentColor is applied to child in surface in jetpack compose 【发布时间】:2022-01-18 12:37:51 【问题描述】:

contentColor 如何在 Jetpack compose 内部影响 Surface 的子级,例如在本例中,文本颜色将为青色。

【问题讨论】:

这里的问题到底是什么?您是在问表面如何使用颜色和内容颜色参数? 谢谢@Jakoss,你的回答确实解释了我需要什么。 【参考方案1】:

我们来看Surface代码:

@Composable
private fun Surface(
    modifier: Modifier,
    shape: Shape,
    color: Color,
    contentColor: Color,
    border: BorderStroke?,
    elevation: Dp,
    clickAndSemanticsModifier: Modifier,
    content: @Composable () -> Unit
) 
    val elevationOverlay = LocalElevationOverlay.current
    val absoluteElevation = LocalAbsoluteElevation.current + elevation
    val backgroundColor = if (color == MaterialTheme.colors.surface && elevationOverlay != null) 
        elevationOverlay.apply(color, absoluteElevation)
     else 
        color
    
    CompositionLocalProvider(
        LocalContentColor provides contentColor,
        LocalAbsoluteElevation provides absoluteElevation
    ) 
        Box(
            modifier
                .shadow(elevation, shape, clip = false)
                .then(if (border != null) Modifier.border(border, shape) else Modifier)
                .background(
                    color = backgroundColor,
                    shape = shape
                )
                .clip(shape)
                .then(clickAndSemanticsModifier),
            propagateMinConstraints = true
        ) 
            content()
        
    

您可以在此处看到Surface 正在为LocalContentColor 设置CompositionLocalProvider。许多 Material 可组合物使用 LocalContentColor 作为其颜色的默认值,在您的示例中为 Text

@Composable
fun Text(
    text: AnnotatedString,
    modifier: Modifier = Modifier,
    color: Color = Color.Unspecified,
    fontSize: TextUnit = TextUnit.Unspecified,
    fontStyle: FontStyle? = null,
    fontWeight: FontWeight? = null,
    fontFamily: FontFamily? = null,
    letterSpacing: TextUnit = TextUnit.Unspecified,
    textDecoration: TextDecoration? = null,
    textAlign: TextAlign? = null,
    lineHeight: TextUnit = TextUnit.Unspecified,
    overflow: TextOverflow = TextOverflow.Clip,
    softWrap: Boolean = true,
    maxLines: Int = Int.MAX_VALUE,
    inlineContent: Map<String, InlineTextContent> = mapOf(),
    onTextLayout: (TextLayoutResult) -> Unit = ,
    style: TextStyle = LocalTextStyle.current
) 
    val textColor = color.takeOrElse 
        style.color.takeOrElse 
            LocalContentColor.current.copy(alpha = LocalContentAlpha.current)
        
    
    val mergedStyle = style.merge(
        TextStyle(
            color = textColor,
            fontSize = fontSize,
            fontWeight = fontWeight,
            textAlign = textAlign,
            lineHeight = lineHeight,
            fontFamily = fontFamily,
            textDecoration = textDecoration,
            fontStyle = fontStyle,
            letterSpacing = letterSpacing
        )
    )
    BasicText(
        text,
        modifier,
        mergedStyle,
        onTextLayout,
        overflow,
        softWrap,
        maxLines,
        inlineContent
    )

尤其是这部分:

val textColor = color.takeOrElse 
    style.color.takeOrElse 
        LocalContentColor.current.copy(alpha = LocalContentAlpha.current)
    

在这里您可以看到Text 正在尝试将颜色定义为参数。如果是Unspecified,它会尝试从TextStyle 中获取一个。如果那里没有颜色 - Text 正在使用来自 LocalContentColor.current 的值(与 LocalContentAlpha 混合,但这是另一个问题的主题)。

【讨论】:

以上是关于如何在jetpack compose中将contentColor应用于表面中的孩子的主要内容,如果未能解决你的问题,请参考以下文章

如何在jetpack compose中将contentColor应用于表面中的孩子

jetpack compose 将参数传递给 viewModel

Jetpack Compose ScrollableTabRow 如何调整最小宽度

如何在jetpack compose上回收webview?

如何在 Jetpack compose 中制作可重用的组件?

如何在jetpack compose中定义不同的屏幕