Updating a single LazyColumn item on state changes

395 views Asked by At

I need to show favourite sessions in my LazyRow which is item of LazyColumn, but if the favourites sessions list cahnges, to update the content in the LazyRow I need to scroll down while LazyRow is completely disappears at the top, and then return to my LazyRow.

Here is my code:

@Composable
fun SessionsScreen(onSessionClick: (Session) -> Unit, viewModel: SessionsViewModel = 
hiltViewModel()) {
    val sessionsStateFlow by viewModel.sessionsStateFlow.collectAsState()
    val favouriteStateFlow by viewModel.favouritesStateFlow.collectAsState()

    LazyColumn(
        modifier = Modifier
            .padding(horizontal = 20.dp)
            .fillMaxSize()
    ) {
        favourite(favouriteStateFlow)
    }
}


fun LazyListScope.favourite(favouritesState: List<Session>) {
    item {
        LazyRow {
            if (favouritesState.isEmpty()) {
                item { Text(text = stringResource(id = R.string.no_favourites)) }
            }
            items(favouritesState) {
                Favourite(it)
            }
        }
    }
}
1

There are 1 answers

1
NewPartizal On

To update the content in the LazyRow when the list of favorite sessions changes, you should make use of the key parameter in the items function. This ensures that Compose can differentiate between different items and update them correctly.

    @Composable
    fun SessionsScreen(onSessionClick: (Session) -> Unit, viewModel: SessionsViewModel = hiltViewModel()) {
        val sessionsStateFlow by viewModel.sessionsStateFlow.collectAsState()
        val favouriteStateFlow by viewModel.favouritesStateFlow.collectAsState()
    
        LazyColumn(
            modifier = Modifier
                .padding(horizontal = 20.dp)
                .fillMaxSize()
        ) {
            favourite(favouriteStateFlow)
        }
    }
    
    fun LazyListScope.favourite(favouritesState: List<Session>) {
        item {
            LazyRow {
                if (favouritesState.isEmpty()) {
                    item { Text(text = stringResource(id = R.string.no_favourites)) }
                }
                items(favouritesState) { session ->
                    Favourite(session, key = session.id) {
                        // Add any interaction logic here
                    }
                }
            }
        }
    }
    
    @Composable
    fun Favourite(session: Session, onClick: () -> Unit) {
        // Your Favourite item composable content here
        // For example:
        Box(
            modifier = Modifier
                .padding(8.dp)
                .clickable { onClick() }
        ) {
            Text(text = session.title)
        }

}