求助: 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)
                }
            }
        }
    }
相关推荐
sun00770012 小时前
android ndk编译valgrind
android
AI视觉网奇13 小时前
android studio 断点无效
android·ide·android studio
jiaxi的天空13 小时前
android studio gradle 访问不了
android·ide·android studio
No Silver Bullet14 小时前
android组包时会把从maven私服获取的包下载到本地吗
android
catchadmin14 小时前
PHP serialize 序列化完全指南
android·开发语言·php
tangweiguo0305198715 小时前
Kable使用指南:Android BLE开发的现代化解决方案
android·kotlin
00后程序员张18 小时前
iOS App 混淆与资源保护:iOS配置文件加密、ipa文件安全、代码与多媒体资源防护全流程指南
android·安全·ios·小程序·uni-app·cocoa·iphone
柳岸风19 小时前
Android Studio Meerkat | 2024.3.1 Gradle Tasks不展示
android·ide·android studio
编程乐学19 小时前
安卓原创--基于 Android 开发的菜单管理系统
android
whatever who cares21 小时前
android中ViewModel 和 onSaveInstanceState 的最佳使用方法
android