Jetpack Compose 中的 adjustViewBounds 模拟
adjustViewBounds analogue in Jetpack Compose
我正在尝试根据图像比例使图像占据容器宽度并具有高度。在 XML 中,我会在 ImageView
上使用 adjustViewBounds
。 Compose 中有类似物吗?如果没有,我该如何实现?
0.1.0-dev09 更新
SimpleImage
已被弃用并被 Image
取代,后者更具可定制性 - 至少它允许设置修饰符。保持图像比例的总体思路保持不变:
val image = imageResource(R.drawable.android_studio_logo)
val imageRatio = image.width.toFloat() / image.height.toFloat()
Image(
image = image,
contentScale = ContentScale.Crop,
modifier = LayoutWidth.Fill + LayoutAspectRatio(imageRatio)
)
0.1.0-dev06 的旧答案
我认为 0.1.0-dev06 目前不支持像 adjustViewBounds
这样的东西。
查看源代码,SimpleImage
好像不能自定义。它所做的只是在 Box
上绘制与图像大小完全相同的图像:
@Composable
fun SimpleImage(
image: Image,
tint: Color? = null
) {
with(DensityAmbient.current) {
val imageModifier = ImagePainter(image).toModifier(
scaleFit = ScaleFit.FillMaxDimension,
colorFilter = tint?.let { ColorFilter(it, BlendMode.srcIn) }
)
Box(LayoutSize(image.width.toDp(), image.height.toDp()) + ClipModifier + imageModifier)
}
}
但基于该实现,可以通过使用不同的大小修饰符来实现类似 adjustViewBounds
的效果。我们可以应用 LayoutWidth.Fill
代替特定的确切尺寸来占据整个宽度,然后使用 LayoutAspectRatio
调整高度,图像的比例为:
val image = imageResource(R.drawable.android_studio_logo)
val imageRatio = image.width.toFloat() / image.height.toFloat()
val imageModifier = ImagePainter(image).toModifier(scaleFit = ScaleFit.FillMaxDimension)
Box(LayoutWidth.Fill + LayoutAspectRatio(imageRatio) + imageModifier)
当然,为了更好的可重用性和可读性,我们可以将其包装在一个函数中。
结果如下:
在版本1.0.0-alpha06时,它与接受的答案相似。
例如矢量资源,代码如下
@Composable
fun VectorImage(asset: VectorAsset) {
val imageRatio = asset.defaultWidth.value / asset.defaultHeight.value
Image(
asset = asset,
contentScale = ContentScale.Fit,
modifier = Modifier.aspectRatio(imageRatio).fillMaxWidth()
)
}
我正在尝试根据图像比例使图像占据容器宽度并具有高度。在 XML 中,我会在 ImageView
上使用 adjustViewBounds
。 Compose 中有类似物吗?如果没有,我该如何实现?
0.1.0-dev09 更新
SimpleImage
已被弃用并被 Image
取代,后者更具可定制性 - 至少它允许设置修饰符。保持图像比例的总体思路保持不变:
val image = imageResource(R.drawable.android_studio_logo)
val imageRatio = image.width.toFloat() / image.height.toFloat()
Image(
image = image,
contentScale = ContentScale.Crop,
modifier = LayoutWidth.Fill + LayoutAspectRatio(imageRatio)
)
0.1.0-dev06 的旧答案
我认为 0.1.0-dev06 目前不支持像 adjustViewBounds
这样的东西。
查看源代码,SimpleImage
好像不能自定义。它所做的只是在 Box
上绘制与图像大小完全相同的图像:
@Composable
fun SimpleImage(
image: Image,
tint: Color? = null
) {
with(DensityAmbient.current) {
val imageModifier = ImagePainter(image).toModifier(
scaleFit = ScaleFit.FillMaxDimension,
colorFilter = tint?.let { ColorFilter(it, BlendMode.srcIn) }
)
Box(LayoutSize(image.width.toDp(), image.height.toDp()) + ClipModifier + imageModifier)
}
}
但基于该实现,可以通过使用不同的大小修饰符来实现类似 adjustViewBounds
的效果。我们可以应用 LayoutWidth.Fill
代替特定的确切尺寸来占据整个宽度,然后使用 LayoutAspectRatio
调整高度,图像的比例为:
val image = imageResource(R.drawable.android_studio_logo)
val imageRatio = image.width.toFloat() / image.height.toFloat()
val imageModifier = ImagePainter(image).toModifier(scaleFit = ScaleFit.FillMaxDimension)
Box(LayoutWidth.Fill + LayoutAspectRatio(imageRatio) + imageModifier)
当然,为了更好的可重用性和可读性,我们可以将其包装在一个函数中。
结果如下:
在版本1.0.0-alpha06时,它与接受的答案相似。
例如矢量资源,代码如下
@Composable
fun VectorImage(asset: VectorAsset) {
val imageRatio = asset.defaultWidth.value / asset.defaultHeight.value
Image(
asset = asset,
contentScale = ContentScale.Fit,
modifier = Modifier.aspectRatio(imageRatio).fillMaxWidth()
)
}