1

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

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

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

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
)

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

4

1 回答 1

7

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

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

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

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

此参数使您的视图下载并放入图像的完整大小的内存中,而不针对当前视图进行优化。所以小心使用它,只有当你确定图像不会太大并且你真的不能添加使用大小修饰符时。


如果图像正在加载但仍然没有占用足够的空间,您可以像这样设置纵横比:

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
        )
)

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

于 2021-08-19T13:29:27.187 回答