I'm trying to make an image take up container width and have height based on image ratio. In XML, I would use adjustViewBounds on ImageView. Is there an analogue in Compose? If not, how can I achieve this?
2 Answers
Update for 0.1.0-dev09
SimpleImage is deprecated and replaced by Image which is bit more customisable - at least it allows to set modifiers. The general idea of maintaining image ratio stays the same:
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)
)
Old answer for 0.1.0-dev06
I don't think that something like adjustViewBounds is currently supported out of the box in 0.1.0-dev06.
By looking at the source code, SimpleImage doesn't seem to be customizable. All it does is drawing the image over the Box with exact same size as the image:
@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)
}
}
But based on that implementation, effect like adjustViewBounds can be achieved by using different size modifier. Instead of specific exact size we can apply LayoutWidth.Fill to occupy entire width and then adjust height using LayoutAspectRatio with the ratio of the image:
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)
Of course for better reusability and readability we can wrap it in a function.
Here is how the result looks like:
At the time of version 1.0.0-alpha06, it's similar to the accepted answer.
For example, for vector resources, the code is as follows.
@Composable
fun VectorImage(asset: VectorAsset) {
val imageRatio = asset.defaultWidth.value / asset.defaultHeight.value
Image(
asset = asset,
contentScale = ContentScale.Fit,
modifier = Modifier.aspectRatio(imageRatio).fillMaxWidth()
)
}
