Reputation: 1
New to Jetpack compose, can someone explain why when i select an item in LazyRow and pass that url to the Image it will recomposed the whole row again? HOw should i be using the movieSelector variable?
@Composable
fun MovieHorizontalCarousel(viewModel: MovieViewModel = MovieViewModel()) {
val movies: LazyPagingItems<Movie> = viewModel.movies.collectAsLazyPagingItems()
Column(
modifier = Modifier
.fillMaxSize()
) {
val movieSelector = remember { mutableStateOf("") }
Carousel(
movies = movies,
onMovieSelected = { url -> movieSelector.value = url },
Modifier
.fillMaxWidth()
.height(100.dp)
)
MoviePreview(
movieSelector.value,
modifier = Modifier
.fillMaxWidth()
.weight(1f)
)
}
}
@Composable
fun MoviePreview(url: String,
modifier: Modifier = Modifier) {
AsyncImage(
modifier = modifier
.fillMaxSize()
.background(Purple40),
model = url,
contentDescription = "Preview"
)
}
@Composable
fun Carousel(movies: LazyPagingItems<Movie>,
onMovieSelected: (String) -> Unit,
modifier: Modifier = Modifier) {
LazyRow(
modifier = modifier
.wrapContentSize()
.background(Purple80),
//horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalAlignment = Alignment.CenterVertically
) {
items (
count = movies.itemCount,
key = { index -> movies[index]?.id ?: index }
//key = movies.itemKey{ item -> item.id }
) { index ->
movies[index]?.let {
MovieCarouselItem(movie = it,
onMovieSelected = onMovieSelected)
}
}
}
}
@Composable
fun MovieCarouselItem (movie: Movie,
onMovieSelected: (String) -> Unit,
modifier: Modifier = Modifier) {
AsyncImage(
modifier = modifier
.size(81.dp)
.clickable {
onMovieSelected("https://image.tmdb.org/t/p/w500${movie.posterPath}")
},
model = "https://image.tmdb.org/t/p/w500${movie.posterPath}",
contentDescription = "Movie Thumbnail" ,
contentScale = ContentScale.Crop,
placeholder = painterResource(id = R.drawable.photo)
)
}
I am trying to display the image that the user selected from the lazyrow, it updated the image but also recomposed the list of movies.
Upvotes: 0
Views: 51
Reputation: 431
Move the selection state outside the Column :
@Composable
fun MovieHorizontalCarousel(viewModel: MovieViewModel = MovieViewModel()) {
val movies: LazyPagingItems<Movie> = viewModel.movies.collectAsLazyPagingItems()
// Hoist state to avoid unnecessary recomposition of Carousel
var selectedMovieUrl by remember { mutableStateOf("") }
Column(
modifier = Modifier
.fillMaxSize()
) {
Carousel(
movies = movies,
onMovieSelected = { url -> selectedMovieUrl = url },
modifier = Modifier
.fillMaxWidth()
.height(100.dp)
)
MoviePreview(
url = selectedMovieUrl,
modifier = Modifier
.fillMaxWidth()
.weight(1f)
)
}
}
Upvotes: 0