我使用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 获取的资源?
从互联网下载的图像通常会显示为
AsyncImage
,但整个异步的事情不会与@Preview
一起工作。遗憾的是,因为预览是调试用户界面的最快方式。
但是,
AsyncImage
有一个功能即使在预览中也能工作 - placeholder
画家。
这种快速解决方法不会增加太多复杂性,并且可以适应不同的情况:
DrawableRes
标识符,并使用它来初始化占位符的绘制器。我添加了一个示例(您可能会认为它是两栖代码实验室的一部分):
@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)
}
}