You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Compose中Glide/Coil加载Bitmap及LazyColumn滚动卡顿解决

问题:Jetpack Compose中用Glide/Coil加载Bitmap并解决LazyColumn滚动卡顿

场景说明

在Jetpack Compose开发中,需要将图片加载到GlideImage、CoilImage或原生Image组件中。图片来源分两种:drawable资源(如image.jpg)或手机相册Uri,目前已能将图片解码为Bitmap,想了解如何用Glide和Coil直接加载该Bitmap,同时解决LazyColumn滚动时的严重卡顿问题。

当前代码实现

LazyColumn列表代码

LazyColumn(
    state = listState
) {
    itemsIndexed(
        items = listCycle,  // 数据来自ViewModel: val listCycle by cycleVM.cycles.collectAsState()
    ) { _, it ->
        CycleItemCard(cycle = it, navHostController)
    }
}

列表项CycleItemCard代码

@Composable
fun CycleItemCard(
    @PreviewParameter(SampleCycleProvider::class) cycle: Cycle,
    navHost: NavHostController
) {
    val context = LocalContext.current
    Card(
        modifier = Modifier
            .fillMaxWidth()
            .padding(1.dp)
            .clickable {
                navHost.navigate(NavigationItem.DetailCycleNavigationItem.routeWithId(cycle.id))
            },
        elevation = CardDefaults.cardElevation(0.dp),
        shape = RoundedCornerShape(0.dp)
    ) {
        Row(
            verticalAlignment = Alignment.CenterVertically,
            modifier = Modifier.background(MaterialTheme.colorScheme.background)
        ) {
/////////图片加载部分
        Image( modifier = Modifier
            .padding(8.dp)
            .height(50.dp)
            .width(50.dp)
            .clip(CircleShape),
                contentScale = ContentScale.Crop,
                painter = rememberAsyncImagePainter(getImage(cycle, context)),
                contentDescription ="" )
  ////// 图片加载结束           
            Column(
                modifier = Modifier
                    .fillMaxWidth()
            ) {
                Text(
                    text = cycle.title!!,
                    style = MyTextTitleLabel16,
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis
                )

                if (!cycle.isDefaultType) {
                    Divider(
                        modifier = Modifier
                            .height(1.dp)
                            .padding(end = 8.dp)
                            .background(Color.Black)
                    )
                }

                if (!cycle.isDefaultType) {
                    Box(
                        modifier = Modifier
                            .align(Alignment.End)
                            .padding(end = 8.dp, top = 4.dp)
                    ) {
                        Text(
                            text = cycle.finishStringFormatDate,
                            fontSize = 12.sp,
                            color = Color(0xFF6c6c70)
                        )
                    }
                }
            }
        }
    }
}

图片解码函数getImage

fun getImage(cycle: Cycle, context: Context): Bitmap {
    val name = context.packageName
    var source: ImageDecoder.Source
    try {
        if (cycle.image != null) {
            source = ImageDecoder.createSource(context.contentResolver, Uri.parse(cycle.image))
        } else {
            val id = context.resources.getIdentifier(cycle.defaultImg, "drawable", name)
            source = ImageDecoder.createSource(context.resources, id)
        }
    } catch (e: NullPointerException) {
        val id = context.resources.getIdentifier("drew", "drawable", name)
        source = ImageDecoder.createSource(context.resources, id)
    }
    return ImageDecoder.decodeBitmap(source)
}

尝试的异步加载实现(不确定正确性)

// 在CycleItemCard中添加的代码
val image = remember {
    mutableStateOf<Bitmap?>(
        Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888).apply {
            eraseColor(context.resources.getColor(R.color.colorBackgroundConstrateLayout))
        }
    )
}
LaunchedEffect(key1 = true) {
    coroutineScope {
        launch(Dispatchers.IO) {
            image.value = getImage(cycle, context, name)
        }
    }
}
// 替换原Image组件
Image(
    modifier = Modifier
        .padding(8.dp)
        .height(50.dp)
        .width(50.dp)
        .clip(CircleShape),
    contentScale = ContentScale.Crop,
    bitmap = image.value!!.asImageBitmap(),
    contentDescription = ""
)

需求

  • 用Glide和Coil加载已解码Bitmap的正确实现方式
  • 彻底解决LazyColumn滚动卡顿的方案

内容的提问来源于stack exchange,提问作者Сергей В

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 17:23:20