Maciej S
11/30/2022, 11:49 AMMaciej S
11/30/2022, 11:50 AMsealed interface AvatarUiModel {
data class ParticipantInitial(val value: String) : AvatarUiModel
object DraftIcon : AvatarUiModel
}
And a composable that takes this type as a param, like
@Composable
fun Avatar(
modifier: Modifier = Modifier,
avatarUiModel: AvatarUiModel
) {
...
that is a part of lazy column’s item composable, I can see in the layout inspector’s recomposition counts that the Avatar
composable is being recomposed all the time while scrolling through the list. This is not the case if I simply use a sealed class, like
sealed class AvatarUiModel {
data class ParticipantInitial(val value: String) : AvatarUiModel()
object DraftIcon : AvatarUiModel()
}
If I do that, I can see that the Avatar
recompositions are being skipped while scrolling, as expected.
The compose compiler report marks the Avatar
composable as skippable when using the interface, however, the param is not marked as stable (see the attached screenshot).
Is that behaviour expected?Zach Klippenstein (he/him) [MOD]
11/30/2022, 11:31 PMLeland Richardson [G]
11/30/2022, 11:47 PMMaciej S
12/01/2022, 8:26 AMAvatar
composable:
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun MailboxItem(
modifier: Modifier = Modifier,
item: MailboxItemUiModel,
onItemClicked: (MailboxItemUiModel) -> Unit,
onOpenSelectionMode: () -> Unit
) {
Box(
modifier = ...
) {
MailboxItemLayout(
avatar = { Avatar(avatarUiModel = item.avatar) },
...
)
}
}
and the MailboxItem
is called from a lazy column:
@Composable
@OptIn(ExperimentalFoundationApi::class)
private fun MailboxItemsList(
listState: LazyListState,
items: LazyPagingItems<MailboxItemUiModel>,
actions: MailboxScreen.Actions
) {
LazyColumn(
state = listState,
modifier = ...
) {
items(
items = items,
key = { it.id }
) { item ->
item?.let {
MailboxItem(
modifier = Modifier.animateItemPlacement(),
item = item,
onItemClicked = actions.onNavigateToMailboxItem,
onOpenSelectionMode = actions.onOpenSelectionMode
)
}
}
}
}
Leland Richardson [G]
12/01/2022, 6:00 PMitem.avatar
is, so it ends up being "unstable". Theoretically we could do better here because we could infer a sealed interface as being always stable if we know that all of its implementations are always stable. We don't currently do that but it is a good ideaMaciej S
12/01/2022, 6:17 PMLeland Richardson [G]
12/01/2022, 8:23 PMMaciej S
12/05/2022, 8:02 AMMaciej S
12/15/2022, 10:44 AM