如何创建根据远程加载的图像大小自动调整大小的 Jetpack Compose 图像?

Eug*_*ene 8 android android-jetpack-compose coil

我想显示具有以下规则的图像:

  • 该图像是远程的,需要在运行时加载。
  • 在加载图像之前我们不知道图像大小是多少。
  • 视图Image应采用父级的完整宽度,并且应自动调整其高度以匹配远程加载的图像,以便不会发生裁剪/拉伸。

我尝试使用线圈依赖项,我有以下代码:

Image(
    painter = rememberImagePainter(viewModel.fullImageUrl),
    contentDescription = null,
    contentScale = ContentScale.FillHeight,
    modifier = Modifier
        .fillMaxWidth()
        .aspectRatio(3.21428f) // TODO: Figure out how to set height/ratio based on image itself
)
Run Code Online (Sandbox Code Playgroud)

当我删除ImagecontentScalemodifier,它的高度似乎总是为零。我不确定在 Coil 加载图像文件后确定其自身的大小时应该做什么来填充Image其父级的最大宽度。

Phi*_*hov 23

当您使用 设置灵活宽度 时fillMaxWidth,您需要ContentScale.FillWidth使用contentScale

Image(
    painter = rememberImagePainter(
        "https://via.placeholder.com/300.png",
    ),
    contentDescription = null,
    contentScale = ContentScale.FillWidth,
    modifier = Modifier
        .fillMaxWidth()
)
Run Code Online (Sandbox Code Playgroud)

如果您的图像具有足够的优先级,则以下内容将正常工作。但在某些情况下coil不会开始加载,因为它会认为图像大小为零,因此不需要显示它。size(OriginalSize)对于这种情况,您可以向构建器添加参数:

rememberImagePainter(
    "https://via.placeholder.com/300.png",
    builder = {
        size(OriginalSize)
    }
)
Run Code Online (Sandbox Code Playgroud)

此参数使您的视图下载完整大小的图像并将其放入内存中,而不针对当前视图进行优化。因此,只有当您确定图像不会太大并且您确实无法添加使用尺寸修改器时,请小心使用它。


如果图像正在加载但仍然没有足够的空间,您可以设置宽高比,如下所示:

val painter = rememberImagePainter("https://via.placeholder.com/300.png")
Image(
    painter = painter,
    contentDescription = null,
    contentScale = ContentScale.Fit,
    modifier = Modifier
        .fillMaxWidth()
        .then(
            (painter.state as? ImagePainter.State.Success)
                ?.painter
                ?.intrinsicSize
                ?.let { intrinsicSize ->
                    Modifier.aspectRatio(intrinsicSize.width / intrinsicSize.height)
                } ?: Modifier
        )
)
Run Code Online (Sandbox Code Playgroud)

如果这些都没有帮助并且painter.state没有改变Empty,请尝试硬编码高度?: Modifier.height(10.dp)以让图像开始加载

  • @Eugene 看起来你还没有尝试过我的最新建议 `builder = { size(OriginalSize) }`,这适用于你的例子 (2认同)