Compose 图片加载最佳实践:Coil 集成与缓存策略

2024-05-24 · 22 min · 图片加载

图片加载是移动应用中最常见的需求之一。Coil(Coroutine Image Loader)是专为 Kotlin 和 Compose 设计的现代图片加载库,提供了简洁的 API 和出色的性能。

一、AsyncImage 基础

@Composable
fun SimpleImage(url: String) {
    AsyncImage(
        model = url,
        contentDescription = "图片描述",
        modifier = Modifier.size(200.dp)
    )
}

完整配置

AsyncImage(
    model = ImageRequest.Builder(LocalContext.current)
        .data(url)
        .crossfade(true)
        .build(),
    contentDescription = "图片",
    modifier = Modifier
        .fillMaxWidth()
        .clip(RoundedCornerShape(12.dp)),
    contentScale = ContentScale.Crop,
    placeholder = painterResource(R.drawable.placeholder),
    error = painterResource(R.drawable.error)
)

二、SubcomposeAsyncImage

SubcomposeAsyncImage(
    model = url,
    contentDescription = "图片"
) {
    when (painter.state) {
        is AsyncImagePainter.State.Loading -> {
            CircularProgressIndicator()
        }
        is AsyncImagePainter.State.Error -> {
            Icon(Icons.Default.BrokenImage, "加载失败")
        }
        else -> {
            SubcomposeAsyncImageContent()
        }
    }
}

三、图片变换

AsyncImage(
    model = ImageRequest.Builder(context)
        .data(url)
        .transformations(
            CircleCropTransformation(),
            RoundedCornersTransformation(16f),
            BlurTransformation(context, radius = 10f)
        )
        .build(),
    contentDescription = null
)

四、缓存策略

AsyncImage(
    model = ImageRequest.Builder(context)
        .data(url)
        .memoryCachePolicy(CachePolicy.ENABLED)
        .diskCachePolicy(CachePolicy.ENABLED)
        .networkCachePolicy(CachePolicy.ENABLED)
        .build(),
    contentDescription = null
)

五、预加载

@Composable
fun PreloadImages(urls: List<String>) {
    val context = LocalContext.current
    val imageLoader = LocalImageLoader.current
    
    LaunchedEffect(urls) {
        urls.forEach { url ->
            val request = ImageRequest.Builder(context)
                .data(url)
                .build()
            imageLoader.enqueue(request)
        }
    }
}

六、最佳实践

总结