LazyColumn с изображением из источника растрового изображения мигает / мигает
Я новичок в Jetpack Compose. В настоящее время я разрабатываю приложение для чата. Прошу пользователя выбрать изображение из галереи или сделать снимок с камеры. Затем я сохраняю файл Uri в базе данных и затем слушаю список всех сообщений. Когда этот список обновляется, это изображение перекомпоновывается и мигает.
Список сообщений в модели просмотра:
private var _messages = MutableStateFlow<List<ChatUiMessage>>(mutableListOf())
val messages: StateFlow<List<ChatUiMessage>> = _messages
...
private fun observeMessages() {
viewModelScope.launch {
chatManager.observeMessagesFlow()
.flowOn(dispatcherIO)
.collect {
_messages.emit(it)
}
}
}
Главный экран чата:
...
val messages by viewModel.messages.collectAsState(listOf())
...
val listState = rememberLazyListState()
LazyColumn(
modifier = modifier.fillMaxWidth(),
reverseLayout = true,
state = listState
) {
itemsIndexed(items = messages) { index, message ->
when (message) {
...
is ChatUiMessage.Image -> SentImageBlock(
message = message
)
...
}
}
}
Мой SentImageBlock:
@Composable
private fun SentImageBlock(message: ChatUiMessage.Image) {
val context = LocalContext.current
val bitmap: MutableState<Bitmap?> = rememberSaveable { mutableStateOf(null) }
bitmap.value ?: run {
LaunchedEffect(Unit) {
launch(Dispatchers.IO) {
bitmap.value = try {
when {
Build.VERSION.SDK_INT >= 28 -> {
val source = ImageDecoder.createSource(context.contentResolver, message.fileUriPath.toUri())
ImageDecoder.decodeBitmap(source)
}
else -> {
MediaStore.Images.Media.getBitmap(context.contentResolver, message.fileUriPath.toUri())
}
}
} catch (e: Exception) {
null
}
}
}
}
Box(
modifier = Modifier
.fillMaxWidth()
.padding(end = 16.dp, top = 16.dp, bottom = 16.dp)
.heightIn(max = 200.dp, min = 200.dp)
) {
bitmap.value?.let {
Image(
bitmap = it.asImageBitmap(),
contentDescription = null,
modifier = Modifier
.wrapContentSize()
.align(Alignment.CenterEnd)
)
}
}
StandardText(text = message.sendFileStatus.toString())
StandardText(text = message.fileType.toString())
}
Я пробовал несколько вещей, и либо изображение всегда мигает.
Пример:
1 ответ
Решение
LazyColumn
повторно использует представления для элементов, используя аргумент, и по умолчанию он равен индексу элемента. Вы можете предоставить правильный
key
(что-то вроде сообщения
id
) для правильного повторного использования представлений:
val messages = listOf(1,2,3)
LazyColumn(
modifier = modifier.fillMaxWidth(),
reverseLayout = true,
state = listState
) {
itemsIndexed(
items = messages,
key = { index, message -> message.id }
) { index, message ->
when (message) {
...
is ChatUiMessage.Image -> SentImageBlock(
message = message
)
...
}
}
}