Jetpack Compose中图像上的渐变

问题描述

这是我的组成部分:

@Composable
fun Cover(
    name: String,imageRes: Int,modifier: Modifier = Modifier.padding(16.dp,8.dp)
) {
    Box(modifier) {
        Card(
            shape = RoundedCornerShape(4.dp),backgroundColor = MaterialTheme.colors.secondary,elevation = 4.dp
        ) {
            Stack {
                Image(
                    imageResource(imageRes),modifier = Modifier
                        .gravity(Alignment.Center)
                        .aspectRatio(2f),contentScale = ContentScale.Crop,)

                Text(
                    text = name,modifier = Modifier
                        .gravity(Alignment.BottomStart)
                        .padding(8.dp),style = MaterialTheme.typography.h6
                )
            }
        }
    }
}

这是它的外观:

cover

我想在Image上方和Text后面显示一个深色渐变,以使文本易于阅读。我猜我将不得不使用LinearGradientRadialGradient,但是由于缺乏文档,我无法使用它。

编辑:This是我要使用Jetpack Compose进行的操作。

解决方法

哇,那只花了几个小时;)

您可以将Modifier.backgroundVerticalGradient一起使用。我使用Column来容纳修改器,并进行了计算以获取图像大小,但是您的解决方案可能会有所不同,您可以使用不同的方式计算或存储大小,然后将修改器放置在其他位置。我在代码中留下了两个TODO,以便您可以调整渐变。

@Composable
fun Cover(
    name: String,imageRes: Int,modifier: Modifier = Modifier.padding(16.dp,8.dp)
) {
    val density = DensityAmbient.current.density
    val width = remember { mutableStateOf(0f) }
    val height = remember { mutableStateOf(0f) }
    Box(modifier) {
        Card(
            shape = RoundedCornerShape(4.dp),backgroundColor = MaterialTheme.colors.secondary,elevation = 4.dp
        ) {
            Stack {
                Image(
                    imageResource(imageRes),modifier = Modifier
                        .gravity(Alignment.Center)
                        .aspectRatio(2f)
                        .onPositioned {
                            width.value = it.size.width / density
                            height.value = it.size.height / density
                        },contentScale = ContentScale.Crop,)
                Column(
                    Modifier.size(width.value.dp,height.value.dp)
                        .background(
                            VerticalGradient(
                                listOf(Color.Transparent,Color.Black),0f,// TODO: set start
                                500f,// TODO: set end
                            )
                        )
                ) {}
                Text(
                    text = name,modifier = Modifier.gravity(Alignment.BottomStart)
                        .padding(8.dp),style = typography.h6,)
            }
        }
    }
}

这是我的示例的样子: sample of card with image background,black to transparent gradient and text

,

您还可以将渐变应用于Image()
定义如下修饰符:

fun Modifier.gradientTint(
        colors: List<Color>,blendMode: BlendMode,brushProvider: (List<Color>,Size) -> LinearGradient
) = composed {
    var size by remember { mutableStateOf(Size.Zero) }
    val gradient = remember(colors,size) { brushProvider(colors,size) }
    drawWithContent {
        drawContent()
        size = this.size
        drawRect(
                brush = gradient,blendMode = blendMode
        )
    }
}

检查 composed (声明Modifier的即时组成,它将针对其修改的每个元素组成)和 {{ 1}} (创建一个drawWithContent,允许开发人员在布局内容之前或之后进行绘制。)方法。

应用 DrawModifier (或VerticalGradientLinearGradient ...):

HorizontalGradient

最后在fun Modifier.verticalGradientTint( colors: List<Color>,blendMode: BlendMode ) = gradientTint(colors,blendMode) { gradientColors,size -> VerticalGradient( colors = gradientColors,startY = 0f,endY = size.height ) } 上使用修饰符:

Image

enter image description here

,

@vitor-ramos 的更新答案

1.0.0-alpha09

import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Card
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.AmbientDensity
import androidx.compose.ui.res.imageResource
import androidx.compose.ui.unit.dp
import tech.abd3lraouf.learn.compose.kombose.ui.theme.typography

@Composable
fun Cover(
    name: String,@DrawableRes imageRes: Int,modifier: Modifier = Modifier
) {
    val image = imageResource(imageRes)
    val density = AmbientDensity.current.density
    val width = remember { mutableStateOf(0f) }
    val height = remember { mutableStateOf(0f) }
    Box(
        modifier
            .padding(16.dp,8.dp)
    ) {
        Card(
            shape = RoundedCornerShape(4.dp),elevation = 4.dp
        ) {
            Box {
                Image(
                    image,modifier = Modifier
                        .align(Alignment.Center)
                        .aspectRatio(2f)
                        .onGloballyPositioned {
                            width.value = it.size.width / density
                            height.value = it.size.height / density
                        },)
                Column(
                    Modifier
                        .size(width.value.dp,height.value.dp)
                        .background(
                            Brush.verticalGradient(
                                listOf(Color.Transparent,image.height * 0.6F,image.height * 1F
                            )
                        )
                ) {}
                Text(
                    text = name,modifier = Modifier
                        .align(Alignment.BottomStart)
                        .padding(8.dp),style = typography.body2,color = Color.White
                )
            }
        }
    }
}

另外,注意渐变如何绘制高度的控制。

输出

Code output

,

直接:

        Card(shape = RoundedCornerShape(8.dp)) {
        Box {
            Image(...)
            Text(
                text = "title",modifier = Modifier
                    .align(Alignment.BottomCenter)
                    .fillMaxWidth()
                    .background(Brush.verticalGradient(0F to Color.Transparent,.5F to Color.Red,1F to Color.Red))
                    .padding(start = 8.dp,end = 8.dp,bottom = 8.dp,top = 16.dp),color = Color.White,style = MaterialTheme.typography.body1,textAlign = TextAlign.Start
            )
        }
    }

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...