https://kotlinlang.org logo
t

Timo Drick

01/28/2021, 3:04 PM
I do want to filter a SnapshotStateList and than use the filtered list in a LazyColumn. How can i do it? Using this code does not work because it does not detect changes in the list and do not filter the list again:
Copy code
val list = remember(snapshotStateList) {
    snapshotStateList.filter { removed.contains(it).not() }
}
As a workaround following code would work but only if the size of the list changes:
Copy code
val list = remember(snapshotStateList.size) {
    snapshotStateList.filter { removed.contains(it).not() }
}
p

Paul Woitaschek

01/28/2021, 3:14 PM
Not at all related but I'd go for
it !in removed
👍 1
a

Adam Powell

01/28/2021, 3:42 PM
Hmm, maybe something like:
Copy code
val filteredList by remember(snapshotStateList, removed) { derivedStateOf { snapshotStateList.filter { it !in removed } }
?
👍 1
t

Timo Drick

01/28/2021, 3:55 PM
Yes that works. Thank you @Adam Powell But i do not really understand why this works.
a

Adam Powell

01/28/2021, 3:59 PM
derivedStateOf
is kind of like
mutableStateOf
, except it returns a read-only snapshot
State<T>
that always contains the latest value of the lambda expression it was constructed with. It caches the result of this computation. If the derived state block reads other snapshot state, the derived state object will invalidate its cache whenever the state it had to read changes.
snapshotStateList is this snapshot state object it reads, so any time snapshotStateList's contents change, it invalidates the derived state.
Then we
remember
that derived state object and use
by
property delegation just like we do with mutableStateOf in composition. We use the snapshot state list and the removed list as remember keys, so we create a new derived state object if we change the whole lists it's based on.
t

Timo Drick

01/28/2021, 4:02 PM
ok thx for the explanation 👍
a

Alexander Sitnikov

01/28/2021, 4:11 PM
Is original example doesn't work because
snapshotStateList
is mutable, and when SlotTable compares remembered value with new value when
snapshotStateList
changes, it sees no difference, because it's the same object?
a

Adam Powell

01/28/2021, 4:46 PM
yep. (It also doesn't consider the
removed
collection changing.)
d

Dominaezzz

01/28/2021, 8:01 PM
Wow, for some reason I assumed
derivedStateOf
didn't need to be remembered. TIL.
t

Timo Drick

01/28/2021, 9:14 PM
so the remember is just in case the referenced object changes right?
d

Dominaezzz

01/28/2021, 9:43 PM
Hmm, I'm starting to question @Adam Powell's use of
removed
(and maybe
snapshotStateList
) in the
remember
keys, shouldn't
derivedStateOf
handle that already?
a

Adam Powell

01/29/2021, 12:08 AM
The
derivedStateOf
lambda closes over the collection instances of
snapshotStateList
and
removed
. If the actual collection instances change, we need to create a new
derivedStateOf
to observe those new collections.
All of the above therefore also presumes that
removed
is either another snapshot state list where the derivedStateOf can observe changes to it or immutable (so that the remember keys will result in a new derived state object if it does change)
137 Views