单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)
}
}
}
}