如何让 Compose Preview 显示从网络加载的图像/矢量资源?

问题描述 投票:0回答:1

我使用Coil从网络加载.svg资源,例如:

@Composable
fun Widget(modifier: Modifier = Modifier) {
    AsyncImage(
        modifier = Modifier.fillMaxSize(),
        model = ImageRequest.Builder(LocalContext.current)
            .decoderFactory(SvgDecoder.Factory())
            .data("https://www.svgrepo.com/show/326168/circle-large.svg")
            .build(),
        contentDescription = null,
        contentScale = ContentScale.FillWidth
    )
}

在设备上运行时加载成功,但在 Compose Preview 中运行时不显示任何资源。如何让 Compose Preview 加载并显示从 Web 获取的资源?

android android-jetpack-compose coil android-jetpack-compose-preview
1个回答
0
投票

从互联网下载的图像通常会显示为

AsyncImage
,但整个异步的事情不会与
@Preview
一起工作。遗憾的是,因为预览是调试用户界面的最快方式。

但是,

AsyncImage
有一个功能即使在预览中也能工作 -
placeholder
画家。

这种快速解决方法不会增加太多复杂性,并且可以适应不同的情况:

  1. 检查图片来源。
  2. 如果它是一个整数,那么我们假设它是一个
    DrawableRes
    标识符,并使用它来初始化占位符的绘制器。
  3. 如果它是一个字符串,那么它可能是一个 URL,所以使用普通的占位符。

我添加了一个示例(您可能会认为它是两栖代码实验室的一部分):

@Composable
fun SomeImageFromInternet(src: String, modifier: Modifier = Modifier) {
    // Things
    // ...
    // More things
    // ...

    AsyncImage(
        // Preview mode will not even try to use the source:
        model = src, 
        contentDescription = null,
        // But preview will fetch the placeholder:
        placeholder = placeHolderOrDrawableRes(src),
        error = painterResource(id = R.drawable.broken_image),
        modifier = Modifier
            .fillMaxWidth()
            .clip(MaterialTheme.shapes.small),
        contentScale = ContentScale.Fit)

    // Yet more things
    // ...
}

/**
 * Returns a [Painter] that is either the one specified
 * in the url, or a default value specified in the placeholder parameter.
 * @param urlOrDrawableRes If it contains an integer, then use it
 * as a [DrawableRes] instead of the placeholder.
 * @param placeholder The [DrawableRes] to use if the
 * url is not an integer.
 * @return An initialised [Painter].
 */
@Composable
fun placeHolderOrDrawableRes(
    urlOrDrawableRes: String,
    @DrawableRes placeholder: Int = R.drawable.loading_image): Painter {
    val drawableRes = urlOrDrawableRes.toIntOrNull()
    return when {
        drawableRes != null -> painterResource(id = drawableRes)
        else -> painterResource(id = placeholder)
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.