求助: Compose开发多图片列表时遇到严重卡顿问题

单Card中图片越多卡顿越严重,用的是Column,用LazyColumn卡顿更严重

Column卡顿表现为低帧率,LazyColumn则是掉帧+低帧率(因为划出界面就重组)\

图片为使用Column现象

用的Coil库加载图片,然后异步显示

不知道是不是因为组件嵌套过多的问题,但是如果不嵌套的话该如何在同一个Card中显示多个图片?求大佬帮助\

卡片部分

kotlin 复制代码
    @Composable
    fun ContentSection(
        modifier: Modifier,
        text: String?,
        location: LocationData?,
        date: Date?,
        expanded: Boolean,
        onExpandClick: () -> Unit,
        textLayoutResult: MutableState<TextLayoutResult?>
    ) {
        Column(
            modifier = Modifier.padding(bottom = 8.dp)
        ) {
            if (text != null) {
                val textStyle = MaterialTheme.typography.bodyMedium
                Text(
                    text = text,
                    style = textStyle,
                    maxLines = if (expanded) Int.MAX_VALUE else 6,
                    overflow = TextOverflow.Ellipsis,
                    modifier = Modifier
                        .padding(16.dp)
                        .clickable(onClick = onExpandClick),
                    onTextLayout = { textLayoutResult.value = it }
                )
            }

            if (location != null) {
                LocationInfo(location)
            }

            if (date != null) {
                DateInfo(date)
            }
        }
    }

    @SuppressLint("MutableCollectionMutableState")
    @Composable
    fun JournalCard(modifier: Modifier, journalData: JournalData) {
        // 控制文本展开状态
        val (expanded, setExpanded) = remember { mutableStateOf(false) }
        val textLayoutResult = remember { mutableStateOf<TextLayoutResult?>(null) }

        // 添加图片预览状态
        val (showImagePreview, setShowImagePreview) = remember { mutableStateOf(false) }
        val (selectedImageIndex, setSelectedImageIndex) = remember { mutableIntStateOf(0) }
        val journalDataRem = remember { mutableStateOf(journalData) }
        ElevatedCard(
            colors = CardDefaults.elevatedCardColors(
                containerColor = MaterialTheme.colorScheme.surfaceVariant,
                contentColor = MaterialTheme.colorScheme.onSurfaceVariant
            ),
            elevation = CardDefaults.cardElevation(defaultElevation = 8.dp),
            modifier = modifier
                .fillMaxWidth()
    //            .padding(horizontal = 16.dp, vertical = 12.dp)
    //            .animateContentSize()
        ) {
            Column {
                // 图片区域
                ImageSection(
                    modifier = modifier,
                    images = journalDataRem.value.images,
                    onImageClick = { index ->
                        setSelectedImageIndex(index)
                        setShowImagePreview(true)
                    }
                )

                // 内容区域
                ContentSection(
                    modifier = modifier,
                    text = journalDataRem.value.text,
                    location = journalDataRem.value.location,
                    date = journalDataRem.value.date,
                    expanded = expanded,
                    onExpandClick = { setExpanded(!expanded) },
                    textLayoutResult = textLayoutResult
                )
            }
        }

        // 显示图片预览
        if (showImagePreview && !journalDataRem.value.images.isNullOrEmpty()) {
            ImageGalleryPreview(
                images = journalDataRem.value.images!!,
                initialIndex = selectedImageIndex,
                onDismiss = { setShowImagePreview(false) }
            )
        }
    }

以下为图片加载部分

kotlin 复制代码
    @Composable
    fun SingleImage(image: Bitmap, onImageClick: (Int) -> Unit) {

        AsyncImage(
            model = ImageRequest.Builder(LocalContext.current)
                .data(image)
                .memoryCachePolicy(CachePolicy.ENABLED)
                .diskCachePolicy(CachePolicy.ENABLED)
                .crossfade(true)
                .size(200) // 增加缩略图尺寸以提高质量
                .build(),
    //        imageLoader = ImageLoadUtils.getImageLoader(),
            contentDescription = "Journal Image",
            contentScale = ContentScale.Crop,
            modifier = Modifier
                .fillMaxSize()
                .clickable { onImageClick(0) },
            clipToBounds = true
        )
    }

    @Composable
    fun TwoImages(images: MutableList<Bitmap>, onImageClick: (Int) -> Unit) {
        Row(modifier = Modifier.fillMaxSize()) {
            Box(
                modifier = Modifier
                    .weight(1f)
                    .fillMaxHeight()
                    .padding(end = 2.dp)
                    .clip(RoundedCornerShape(12.dp))
                    .clickable { onImageClick(0) }
            ) {
                AsyncImage(
                    model =  images[0],
                    contentDescription = "Journal Image 1",
                    contentScale = ContentScale.Crop,
                    imageLoader = ImageLoadUtils.getImageLoader(),
                    modifier = Modifier.fillMaxSize(),
                    clipToBounds = true
                )
            }

            Box(
                modifier = Modifier
                    .weight(1f)
                    .fillMaxHeight()
                    .padding(start = 2.dp)
                    .clip(RoundedCornerShape(12.dp))
                    .clickable { onImageClick(1) }
            ) {
                AsyncImage(
                    model = images[1],
                    contentDescription = "Journal Image 2",
                    contentScale = ContentScale.Crop,
                    imageLoader = ImageLoadUtils.getImageLoader(),
                    modifier = Modifier.fillMaxSize(),
                    clipToBounds = true
                )
            }
        }
    }

    @Composable
    fun ThreeImages(images: MutableList<Bitmap>, onImageClick: (Int) -> Unit) {
        Row(modifier = Modifier.fillMaxSize()) {
            Box(
                modifier = Modifier
                    .weight(0.5f)
                    .fillMaxHeight()
                    .padding(end = 4.dp)
                    .clip(RoundedCornerShape(12.dp))
                    .clickable { onImageClick(0) }
            ) {
                AsyncImage(
                    model = ImageRequest.Builder(LocalContext.current)
                        .data(images[0])
                        .memoryCachePolicy(CachePolicy.ENABLED)
                        .diskCachePolicy(CachePolicy.ENABLED)
                        .crossfade(true)
                        .size(150) // 设置缩略图尺寸
                        .build(),
                    contentDescription = "Journal Image 1",
                    contentScale = ContentScale.Crop,
                    modifier = Modifier.fillMaxSize(),
                    clipToBounds = true
                )
            }

            Column(
                modifier = Modifier
                    .weight(0.5f)
                    .fillMaxHeight(),
                verticalArrangement = Arrangement.spacedBy(4.dp)
            ) {
                Box(
                    modifier = Modifier
                        .weight(0.5f)
                        .fillMaxWidth()
                        .clip(RoundedCornerShape(12.dp))
                        .clickable { onImageClick(1) }
                ) {
                    AsyncImage(
                        model = ImageRequest.Builder(LocalContext.current)
                            .data(images[1])
                            .memoryCachePolicy(CachePolicy.ENABLED)
                            .diskCachePolicy(CachePolicy.ENABLED)
                            .crossfade(true)
                            .size(100) // 设置缩略图尺寸
                            .build(),
                        contentDescription = "Journal Image 2",
                        contentScale = ContentScale.Crop,
                        modifier = Modifier.fillMaxSize(),
                        clipToBounds = true
                    )
                }

                Box(
                    modifier = Modifier
                        .weight(0.5f)
                        .fillMaxWidth()
                        .clip(RoundedCornerShape(12.dp))
                        .clickable { onImageClick(2) }
                ) {
                    AsyncImage(
                        model = ImageRequest.Builder(LocalContext.current)
                            .data(images[2])
                            .memoryCachePolicy(CachePolicy.ENABLED)
                            .diskCachePolicy(CachePolicy.ENABLED)
                            .crossfade(true)
                            .size(100) // 设置缩略图尺寸
                            .build(),
                        contentDescription = "Journal Image 3",
                        contentScale = ContentScale.Crop,
                        modifier = Modifier.fillMaxSize(),
                        clipToBounds = true
                    )
                }
            }
        }
    }

    @Composable
    fun MultipleImages(images: MutableList<Bitmap>, onImageClick: (Int) -> Unit) {
        Row(modifier = Modifier.fillMaxSize()) {
            Box(
                modifier = Modifier
                    .weight(0.5f)
                    .fillMaxHeight()
                    .padding(end = 4.dp)
                    .clip(RoundedCornerShape(12.dp))
                    .clickable { onImageClick(0) }
            ) {
                AsyncImage(
                    model = ImageRequest.Builder(LocalContext.current)
                        .data(images[0])
                        .memoryCachePolicy(CachePolicy.ENABLED)
                        .diskCachePolicy(CachePolicy.ENABLED)
                        .crossfade(true)
                        .size(150) // 设置缩略图尺寸
                        .build(),
                    contentDescription = "Journal Image 1",
                    contentScale = ContentScale.Crop,
                    modifier = Modifier.fillMaxSize(),
                    clipToBounds = true
                )
            }

            Column(
                modifier = Modifier
                    .weight(0.5f)
                    .fillMaxHeight(),
                verticalArrangement = Arrangement.spacedBy(4.dp)
            ) {
                val maxRightImages = minOf(3, images.size - 1)
                for (i in 1..maxRightImages) {
                    Box(
                        modifier = Modifier
                            .weight(1f)
                            .fillMaxWidth()
                            .clip(RoundedCornerShape(12.dp))
                            .clickable { onImageClick(i) }
                    ) {
                        AsyncImage(
                            model = ImageRequest.Builder(LocalContext.current)
                                .data(images[i])
                                .memoryCachePolicy(CachePolicy.ENABLED)
                                .diskCachePolicy(CachePolicy.ENABLED)
                                .crossfade(true)
                                .size(100) // 设置缩略图尺寸
                                .build(),
                            contentDescription = "Journal Image ${i + 1}",
                            contentScale = ContentScale.Crop,
                            modifier = Modifier.fillMaxSize(),
                            clipToBounds = true
                        )

                        if (i == maxRightImages && images.size > maxRightImages + 1) {
                            Box(
                                modifier = Modifier
                                    .fillMaxSize()
                                    .background(Color(0x80000000)),
                                contentAlignment = Alignment.Center
                            ) {
                                Text(
                                    text = "+${images.size - maxRightImages - 1}",
                                    style = MaterialTheme.typography.titleMedium,
                                    color = Color.White
                                )
                            }
                        }
                    }
                }
            }
        }
    }

    @Composable
    fun ImageSection(
        images: MutableList<Bitmap>?,
        onImageClick: (Int) -> Unit,
        modifier: Modifier
    ) {
        if (!images.isNullOrEmpty()) {
            Box(
                modifier = Modifier
                    .fillMaxWidth()
                    .height(200.dp)
                    .clip(RoundedCornerShape(12.dp))
            ) {
                when (images.size) {
                    1 -> SingleImage(images[0], onImageClick)
                    2 -> TwoImages(images, onImageClick)
                    3 -> ThreeImages(images, onImageClick)
                    else -> MultipleImages(images, onImageClick)
                }
            }
        }
    }
相关推荐
Bonnie_cat12 分钟前
Android Framework 之了解系统启动流程二
android
Android采码蜂35 分钟前
SurfaceFlinger11-ITransactionCompletedListener事件监听
android
奥顺互联V1 小时前
如何处理PHP中的编码问题
android·开发语言·php
-seventy-1 小时前
Android 手机启动过程
android
暗影天帝1 小时前
POCO F4刷机color 15
android
每次的天空2 小时前
Android第二次面试总结(项目拷打理论篇)
android
little_fat_sheep2 小时前
【Android】RuntimeShader 应用
android·shader·runtimeshader·agsl·rendereffect
每次的天空2 小时前
kotlin中的模块化结构组件
android·开发语言·kotlin
MSTcheng.5 小时前
【C语言】自定义类型:结构体,联合,枚举(下)
android·java·c语言
博界IT精灵5 小时前
分支与循环(上)
android