组合图像/图标渐变色调。

6
在Compose布局中,是否可以使用渐变对矢量图进行着色?似乎Modifier.background会为其创建背景,因此这不是一个解决方案。类似于ColorFilter的方法目前还不支持它。

你需要自己来实现一些东西。试着深入研究源代码。 - Richard Onslow Roper
1个回答

13

更新:

有一个更简单的解决方案,它来自于@nebulasmoothie对Jetpack Compose中文本渐变的回答

Icon(
     modifier = Modifier
        .graphicsLayer(alpha = 0.99f)
        .drawWithCache {
           onDrawWithContent {
             drawContent()
             drawRect(brushGradient, blendMode = BlendMode.SrcAtop)
           }
        },
     imageVector =  Icons.Default.Favorite,
     contentDescription = null,
    )

ImageVector 通过 RenderVectorGroup 进行渲染,可以为每个 VectorPath 传递一个 VectorConfig。文档说明它应该用于动画,因此我不确定是否可以将其用于渐变,但这是我找到的唯一可以传递 Brush 的地方。

实现 VectorConfig 并使其返回你的渐变给 VectorProperty.Fill

class GradientConfig(private val brush: Brush) : VectorConfig {

    override fun <T> getOrDefault(property: VectorProperty<T>, defaultValue: T): T {
        return when (property) {
            is VectorProperty.Fill -> brush as T
            else -> super.getOrDefault(property, defaultValue)
        }
    }
}

@Composable
fun GradientIcon(image: ImageVector, gradientConfig: GradientConfig) {

    val configs = hashMapOf<String, VectorConfig>(image.root.name to gradientConfig)

    Icon(
        painter = rememberVectorPainter(image = image, configs = configs),
        contentDescription = null,
    )
}

@Composable
fun rememberVectorPainter(image: ImageVector, configs: Map<String, VectorConfig>): VectorPainter {

    return androidx.compose.ui.graphics.vector.rememberVectorPainter(
        defaultWidth = image.defaultWidth,
        defaultHeight = image.defaultHeight,
        viewportWidth = image.viewportWidth,
        viewportHeight = image.viewportHeight,
        name = image.name,
        tintColor = image.tintColor,
        tintBlendMode = image.tintBlendMode,
        content = { _, _ -> RenderVectorGroup(group = image.root, configs = configs) }
    )
}

@Preview(name = "GradientIcon")
@Composable
fun PreviewGradientIcon() {

    val gradient = Brush.linearGradient(
        colors = listOf(
            Color(0xff9F5CFF),
            Color(0xffF0A966)
        ),
        start = Offset(12f, 0f),
        end = Offset(12f, 24f),
    )

    GradientIcon(
        icon = Icons.Filled.Palette,
        gradientConfig = GradientConfig(gradient)
    )
}  

5
现在我们可以添加 .graphicsLayer { compositingStrategy = CompositingStrategy.Offscreen },以避免使用0.99 alpha通道。 - Marco Antonio
.graphicsLayer + .drawWithCache方法是实现的最简单的方式,谢谢你! - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接