Я создаю простое приложение в Jetpack Compose. В разделе «Главная страница» приложения я показываю список элементов. Ничего особенного.
Я делаю это с помощью специальной карточки внутри LazyColumn.
Проблема:
Когда приложение загружается, отображается список, а затем элементы отображаются в первый раз. Затем я прокручиваю вниз, и все элементы отображаются в пользовательской карточке так, как и ожидалось.
Проблема возникает, когда я прокручиваю вверх, а затем снова прокручиваю вниз, в основном перекомпонуя/перерисовывая элементы.
Затем изображение пользовательской карточки игнорирует его ContentScale и его модификатор полностью и нарушает макет. Что-то крайне странное.
Что я пробовал:
- Сначала я пытался создать собственную карту со столбцами и строками.
- Затем я создал его с помощью ConstraintLayout.
- Пытался запомнить модификатор.
- Обычай card, где оно имеет определенную высоту (180.dp) и fillMaxWidth.
- Изображение должно быть размещено на начало пользовательской карточки, ее высота и ширина также должны быть фиксированными (например, ширина: 124.dp, высота: 180.dp).
Код пользовательской карты:Изображения и графическое пояснение происходящего:Код: Выделить всё
@Composable fun ProductCard( data: ProductDisplayData, onClick: (ProductDisplayData) -> Unit = {} ) { val constraints = ConstraintSet { val imageSection = createRefFor("imageSection") val textSection = createRefFor("textSection") constrain(imageSection) { top.linkTo(parent.top) start.linkTo(parent.start) end.linkTo(textSection.start) width = Dimension.value(128.dp) height = Dimension.value(180.dp) } constrain(textSection) { top.linkTo(parent.top) start.linkTo(imageSection.end) bottom.linkTo(parent.bottom) end.linkTo(parent.end) width = Dimension.fillToConstraints height = Dimension.fillToConstraints } } ConstraintLayout(constraints, modifier = Modifier .fillMaxWidth() .clip(RoundedCornerShape(8.dp)) .padding(vertical = 8.dp) .clickable { onClick(data) } ) { if (data.image != null) { Box( modifier = Modifier .layoutId("imageSection") .height(180.dp) .width(128.dp) .clip(RoundedCornerShape(8.dp)) .clipToBounds() ) { Image( bitmap = data.image.asImageBitmap(), contentDescription = "Product Image", modifier = Modifier .fillMaxSize() ) } } Column( modifier = Modifier .layoutId("textSection") .fillMaxWidth() .padding(8.dp), verticalArrangement = Arrangement.spacedBy(4.dp) ) { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { Text( text = data.name, fontWeight = FontWeight.Bold, fontSize = 18.sp, maxLines = 1, overflow = TextOverflow.Ellipsis, modifier = Modifier.weight(1f) ) Text(text = "${data.price}$" ) } Text(text = data.brand, fontWeight = FontWeight.Bold, fontSize = 14.sp) Text(text = data.size, modifier = Modifier, fontWeight = FontWeight.SemiBold, fontSize = 12.sp, fontStyle = FontStyle.Italic) Text(text = data.category, fontWeight = FontWeight.SemiBold, fontSize = 12.sp) LazyRow { items(data.tags) { tag -> Chip( name = tag, isSelected = false, onSelectionChanged = {} ) } } Text( text = data.description, maxLines = 2, overflow = TextOverflow.Ellipsis, fontWeight = FontWeight.Light, fontSize = 12.sp ) } } } - Этот элемент отображается впервые. в LazyColumn

- Это второй раз, по сути, снова прокручивал вверх и вниз. В этом случае contentScale полностью исчез.

- Также обратите внимание на радиус угла (.clip ) изображения при первом показе элемента.

- Угловой радиус (.clip) исчез при втором отображении элемента, поэтому, по сути, модификаторы также исчезают.

Единственная особенность изображения заключается в том, что оно приходит в ответ в виде строки base64 , и оно преобразуется из него в растровое изображение. Вот почему я использую Image, а не Coil (AsyncImage) для отображения изображения.
Я не могу разместить строку base64 для этого MRE из-за ее длины.
Для проверки конвертируйте изображение в строку base64.
Код ProductCard опубликован выше.
Код: Выделить всё
data class ProductDisplayData(
val id: Int,
val name: String,
val description: String,
val size: String,
val ownerName: String,
val ownerID: Int,
val price: String,
val category: String,
val brand: String,
val tags: List,
val image: Bitmap?
)
val products = listOf(
ProductDisplayData(
id = 0,
name = "Polo",
description = "Nice slim fit polo shirt, perfect for casual wear, available in multiple colors",
size = "Small",
price = "120",
image = bitmapFromBase64String,
brand = "Boss",
category = "Shirts",
tags = listOf("Shirts", "Boss", "Slim fit", "Casual", "Polo", "Small"),
ownerName = "John Doe",
ownerID = 0
)
//repeat it until the list overflows...
)
@Composable
fun HomeScreen() {
LazyColumn(
modifier = Modifier.fillMaxWidth(),
contentPadding = PaddingValues(vertical = 16.dp),
) {
items(products) { product ->
ProductCard(
data = product
) { productSelected ->
// do action... irrelevant for this issue.
}
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/785 ... lazycolumn