问题描述
这是我的组成部分:
@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
)
}
}
}
}
这是它的外观:
我想在Image
上方和Text
后面显示一个深色渐变,以使文本易于阅读。我猜我将不得不使用LinearGradient
或RadialGradient
,但是由于缺乏文档,我无法使用它。
编辑:This是我要使用Jetpack Compose进行的操作。
解决方法
哇,那只花了几个小时;)
您可以将Modifier.background
与VerticalGradient
一起使用。我使用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,)
}
}
}
}
,
您还可以将渐变应用于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
(或VerticalGradient
,LinearGradient
...):
HorizontalGradient
最后在fun Modifier.verticalGradientTint(
colors: List<Color>,blendMode: BlendMode
) = gradientTint(colors,blendMode) { gradientColors,size ->
VerticalGradient(
colors = gradientColors,startY = 0f,endY = size.height
)
}
上使用修饰符:
Image
,
@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
)
}
}
}
}
另外,注意渐变如何绘制高度的控制。
输出
,直接:
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
)
}
}