如何更快地加载列表中的位图图像,使用jetpack compose Android

问题描述 投票:0回答:1

我正在尝试使用 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 让我的表现最差。

请随时给我建议,我还在学习阶段。

提前致谢。

kotlin android-jetpack-compose kotlin-coroutines android-bitmap bitmapimage
1个回答
0
投票

我目前正在为此进行后台加载,我的列表上有很多滞后效应:

@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)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.