https://kotlinlang.org logo
Title
m

myanmarking

01/06/2022, 12:35 PM
if i want to change some color based on list scrolling or not, is this the correct approach:
var isScrolling by remember {
        mutableStateOf(lazyListState.isScrollInProgress)
    }
    
    LaunchedEffect(key1 = lazyListState){
        snapshotFlow { lazyListState.isScrollInProgress }.collect {
            isScrolling = it
        }
    }
a

Adam Powell

01/06/2022, 2:53 PM
Why not use
lazyListState.isScrollInProgress
directly?
m

myanmarking

01/06/2022, 3:28 PM
Ya, i dont know. I saw a similar approach in chris banes pager implementation. And he does the following:
LaunchedEffect(item) {
    snapshotFlow { pagerState.currentPage }.collect { page: Int ->        
    }
}
To be honest, i don’t quite know when to use remember vs a simple state variable. Can you point me to the right direction here? still learning
a

Adam Powell

01/06/2022, 3:42 PM
I think I'd need to see the surrounding code to have an opinion on that pager implementation 🙂
m

myanmarking

01/06/2022, 3:46 PM
ok, so imagining i am querying some info from the pagerState, for instance:
state.layoutInfo.visibleItemsInfo.firstOrNull { it.offset > 0 }?.index
If it produces the same output across recomposition, compose just skips it right? So in that case i don’t need remember right ?
a

Adam Powell

01/06/2022, 3:46 PM
Use
mutableStateOf
when you need (a) observability (things recompose/relayout/redraw accordingly if it changes) and/or (b) transactionality (changes made in composition don't become "truth" until the composition or other snapshot successfully commits).
Use
remember
when you need to persist the same value or object across multiple recompositions instead of creating new ones on every recomposition
If you have that expression and you only want to recompose if its final value changes, use
derivedStateOf
so
val firstIndex by derivedStateOf {
  state.layoutInfo.visibleItemsInfo.firstOrNull { it.offset > 0 }?.index
}
m

myanmarking

01/06/2022, 3:49 PM
I am using that index inside an item composable in LazyRow
ok, makes sense i guess. Thanks
a

Adam Powell

01/06/2022, 3:49 PM
derivedStateOf
returns a state object, so if you don't want to recreate that derived state object every recomposition, you can remember it and key it based on what should cause your code to create a new instance:
val firstIndex by remember(state) {
  derivedStateOf {
    state.layoutInfo.visibleItemsInfo.firstOrNull { it.offset > 0 }?.index
  }
}
m

myanmarking

01/06/2022, 3:57 PM
yes. I’m trying to query for the firstVisibleItem, but that attribute of state returns an item with negative offset (my guess is because of the margins). So i need to query using visibleItemInfo. I don’t know if there is a better way
a

Adam Powell

01/06/2022, 4:03 PM
items have a negative offset if they're scrolled partially out of the viewport