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,提问作者Сергей В
相关产品推荐
相关产品推荐

