我正在尝试使用 jetpack compose 加载列中的对象列表。
问题是图像导致屏幕滞后。
这是我的代码 - 单个列表项可组合函数。
fun SoulProfilePreviewSingleItem(
soul: Souls,
soulWinningViewModel: SoulWinningViewModel,
onClick: () -> Unit
) {
val lazyListState = rememberLazyListState()
/* val localImage = if (soul.localImage.isNotBlank())
rememberImagePainter(getBase64StringToImage(soul.localImage)) else null*/
LaunchedEffect(key1 = soulWinningViewModel.nurtureVsFollowUpTabIndex.value) {
lazyListState.animateScrollToItem(0)
// if (soul.localImage.isNotBlank()){
// }
}
val isManaging = soulWinningViewModel.isManagingList.value
var isDeleted by remember {
mutableStateOf(false)
}
val setVisibility: (Boolean) -> Unit = {
isDeleted = it
}
AnimatedVisibility(
visible = isDeleted.not() &&
if (soulWinningViewModel.userIsSearchingFor.value.isNotEmpty() && isManaging.not())
soul.name.contains(soulWinningViewModel.userIsSearchingFor.value, true) ||
soul.followUpActions.toString()
.contains(soulWinningViewModel.userIsSearchingFor.value, true) else
true
) {
with(soul) {
Column {
Box(
modifier = Modifier
.height(60.dp)
.background(MaterialTheme.colorScheme.background)
.fillMaxWidth(),
contentAlignment = Alignment.BottomEnd
) {
Row(
Modifier
.fillMaxSize(),//.clickable { onClick() },
verticalAlignment = Alignment.CenterVertically
) {
Row(
verticalAlignment = Alignment.Top,
modifier = Modifier
.padding(start = brc_DP_small)
.padding(bottom = 6.dp, top = 6.dp)
) {
/*if (soul.localImage.isNotBlank()) {
GlideImage(
model = ,
// Crop, Fit, Inside, FillHeight, FillWidth, None
contentScale = ContentScale.Crop,
// shows an image with a circular revealed animation.
)
Log.e("BITMAP","onResourceReady test")
val image = loadPicture(url = soul.localImage, defaultImage = R.drawable.ic_brc_logo).value
image?.let { img->
Image(
// Can crash this
bitmap =img.asImageBitmap(),
contentDescription = null,
modifier = Modifier
.clip(RoundedCornerShape(50))
.size(30.dp),
contentScale = ContentScale.Crop
)
}
}*/
if (soul.localImage.isNotBlank()) {
// val imageLoader = rememberImagePainter(getBase64StringToImage(soul.localImage))
Image(
// painter = imageLoader
// Can crash this
bitmap = (
getBase64StringToImage(soul.localImage).asImageBitmap()
),
contentDescription = null,
modifier = Modifier
.clip(RoundedCornerShape(50))
.size(30.dp),
contentScale = ContentScale.Crop
)
} else {
Image(
// Can crash this
painterResource(id = R.drawable.ic_brc_logo),
contentDescription = null,
modifier = Modifier
.clip(RoundedCornerShape(50))
.size(30.dp),
contentScale = ContentScale.Crop
)
}
}
Column(
modifier = Modifier
.padding(top = brc_DP_small)
.weight(1f)
.fillMaxWidth()
.fillMaxHeight()
.padding(start = brc_DP_smaller),
verticalArrangement = Arrangement.SpaceBetween
) {
Column(
modifier = Modifier
.weight(1f)
.fillMaxSize()
) {
// This is the place where signle soul is getting showed......
Text(
text = name,
style = if (isManaging.not()) MaterialTheme.typography.labelSmall.copy(
fontWeight = FontWeight(500),
letterSpacing = 0.7.sp
)
else MaterialTheme.typography.labelSmall
.copy(
fontSize = 10.sp
),
modifier = Modifier,
maxLines = 1,
)
if (isManaging.not()) {
Text(
text = SimpleDateFormat(
"dd-MMM-yyyy",
Locale.UK
).format(
createdOn
),
style = MaterialTheme.typography.bodySmall.copy(fontSize = 9.sp),
color = Color.Gray,
modifier = Modifier
)
}
}
if (isBrcMember) {
Text(
text = "BRC Member",
style = MaterialTheme.typography.labelSmall.copy(
fontSize = 7.sp,
fontStyle = FontStyle.Italic
),
color = brc_blue_color,
modifier = Modifier.padding(bottom = brc_DP_smallest)
)
}
}
}
var externClick by remember {
mutableStateOf(false)
}
Column(modifier = Modifier.padding(brc_DP_small)) {
AddSoulFollowUpActionButton(
soul = soul,
soulWinningViewModel = soulWinningViewModel,
visible = soulWinningViewModel.nurtureVsFollowUpTabIndex.value == 1,
externClick = externClick,
onFinished = { externClick = false }
) {
setVisibility(it)
}
}
//TODO:Check Click area ...
Row(modifier = Modifier.fillMaxSize()) {
Spacer(
modifier = Modifier
.fillMaxSize()
.weight(1.4f)
.clickable(
interactionSource = MutableInteractionSource(),
indication = null
) { onClick() })
if (soulWinningViewModel.nurtureVsFollowUpTabIndex.value == 1 || isManaging) {
Spacer(
modifier = Modifier
.fillMaxSize()
.weight(0.6f)
.clickable(
interactionSource = MutableInteractionSource(),
indication = null
) { externClick = !externClick })
}
}
}
Spacer(
modifier = Modifier
.padding(start = 28.dp)
.fillMaxWidth() //.then(if (isManaging.not()) Modifier.width(150.dp) else Modifier.fillMaxWidth())
.height(0.3.dp)
.background(Color.LightGray)
)
}
}
}
}
列表可组合函数的调用者。
forEach {
SoulProfilePreviewSingleItem(
soul = it,
soulWinningViewModel
) {
soulWinningViewModel.currentSoul.value = it
navController.navigate(route = SoulWinningRoutes.PROFILE)
}
}
每当我尝试显示我的灵魂对象的 Image() 时,我都会遇到故障,并且我的屏幕需要更多时间来加载自身。
我将图像作为字符串存储在本地房间数据库中,并尝试检索它并将其转换为位图图像。
对话代码。
fun getBase64StringToImage(base64String: String): Bitmap {
val decodedString: ByteArray = Base64.decode(base64String, Base64.DEFAULT)
val decodedByte = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.size)
return decodedByte
// this is taking a lot of time and making my Ui performance dull.
}
有什么方法可以以良好的性能实现此功能。就像在单独的范围或其他任何东西中加载图像一样。
我已经尝试过使用rememberImagePainter和Glide Coil。请记住ImagePainter 让我的表现最差。
请随时给我建议,我还在学习阶段。
提前致谢。
我目前正在为此进行后台加载,我的列表上有很多滞后效应:
@Composable
fun PictureWithBlurHash(
modifier: Modifier = Modifier,
colorFilter: ColorFilter? = null,
contentScale: ContentScale = ContentScale.Fit,
description: String = "",
filterQuality: FilterQuality = FilterQuality.High,
blurHash: String
) {
val bitmap = remember {
mutableStateOf<Bitmap?>(null)
}
if (bitmap.value == null) {
Box(
contentAlignment = Alignment.Center,
modifier = modifier
) {
Z17Shimmer(modifier = Modifier.fillMaxSize())
}
} else {
bitmap.value?.let {
it.prepareToDraw()
Image(
bitmap = it.asImageBitmap(),
contentDescription = description,
colorFilter = colorFilter,
modifier = modifier,
contentScale = contentScale,
filterQuality = filterQuality
)
}
}
LaunchedEffect(Unit) {
delay(500)
bitmap.value = BlurHashDecoder.decode(blurHash, 140, 140, 1f, false)
}
}