I am writing simple item displaying image and some text, and also having functionality to add item to favorite.
@Composable
fun ItemView(
item: Item,
modifier: Modifier = Modifier,
onFavoriteClick: (Item) -> Unit = {},
) {
Row(modifier = modifier) {
AsyncImage(
model = remember (item.id) {item.url},
contentDescription = "img",
contentScale = ContentScale.Crop,
placeholder = painterResource(id = R.drawable.restaurant_placeholder),
error = painterResource(id = R.drawable.restaurant_placeholder),
modifier = Modifier
.size(48.dp)
.clip(RoundedCornerShape(10)),
)
Text(text = item.name)
IconToggleButton(
checked = isFavourite,
onCheckedChange = remember { { onFavoriteClick(item) } }
) {
Icon(
imageVector = if (item.isFavourite) {
Icons.Filled.Favorite
} else {
Icons.Default.FavoriteBorder
},
contentDescription = null,
)
}
}
}
Without AsyncImage
I noticed that ItemView is not recomposed when being added to favorite (only icon is new), but when I add AsyncImage
whole ItemView
recompose and AsyncImage
as well.
I tried to wrap ContentScale
and Modifier
into remember, but it still didn't work out.
AsyncImage(
model = remember (item.id) {item.url},
contentDescription = "img",
contentScale = remember {ContentScale.Crop},
placeholder = painterResource(id = R.drawable.placeholder),
error = painterResource(id = R.drawable.placeholder),
modifier = remember {Modifier
.size(48.dp)
.clip(RoundedCornerShape(10)) },
)
Also I noticed that when I removed placeholder
and error
I got one recomposition less. I thought is is normal that AsyncImage
will recompose when image is loaded but ItemView
shouldn't. What do I do wrong?
I create that items this way (I think using id as a key makes more sense than hash to not create new item each time it's favorite status change):
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun MainView(vm: ItemViewModel) {
LazyColumn {
items(
count = vm.items.size,
key = { idx -> vm.items[idx].id },
) { idx ->
ItemView(
item = vm.items[idx],
modifier = remember { Modifier.animateItemPlacement() },
onFavoriteClick = remember { vm::onFavoriteClick },
)
}
}
}