I'm using a `mutableStateListOf<T>` but when...
# compose
c
I'm using a
mutableStateListOf<T>
but when I call clear() and then addAll() to it, it seems like compose tries to be "smart" and apply only the changes between the two lists. Is there a way to "opt out" of that behavior? So Im looking to go from this:
Copy code
state.list.clear()
state.list.addAll(networkResult.newItems)
to something like this (completely made up api)
Copy code
state.list.clear().commitTransactionAndWait()
state.list.addAll(networkResult.newItems).commitTransactionAndWait()
For example, if I do this then everything works as expected
Copy code
state.list.clear()
  viewModelScope.launch { 
      delay(500)
state.list.addAll(networkResult.newItems)
  }
j
Make it a var and create a new mutable state list instead of clearing
c
Hm. I thought that would work but still encountering the same issue. new code
Copy code
state.list = mutableStateListOf()
state.list.addAll(networkResult.newItems)
If I do
Copy code
state.list = mutableStateListOf()
  viewModelScope.launch {
    delay(500)
    state.list.addAll(networkResult.newItems)
  }
then I'm back in business.
e
Does it still happen if you make the changes off the main thread?
c
Hm. How would I do that? Just supply a different dispatchers in the launch method? or do you mean something else?
e
Something like:
Copy code
viewModelScope.launch(Dispatchers.Default) {
  state.list.clear()
  state.list.addAll(networkResult.newItems)
}
a
what code is reading this list and what behavior are you looking to achieve?
c
So I'm basically building like a google forms app. So the networkResult.newItems is a description of input fields. Those input field descriptions are mapped to actual items that are drawn on the screen. Now this works without any issues. But you can pull to refresh. So upon pull to refresh, I want to clear all form fields, and add the new ones from the network. This seems to work without any issues except that OutlinedInputFields seems to remember the previous items label that was there.
I think i will have to try to work on a minimal reproducible project here because this makes no sense to me on why my items have visual artifacting.
a
previous item's label?
it sounds like something may be over-remembering somewhere
c
Yep... I was able to repro! Adding a gist now. Actually wayyyy less code than I thought I'd need.
Here you can see it in action. 1. Click the button to make a "fake" network call. 2. clear the list of items, then add all items from the network call 3. click on an item to pretend like you filled it in 4. click the button again to pretend like you refreshed, and now you have new data 5. observer that you have a gap on the label even though you called list.clear() and then list.addAll()
And of course, if I use JW advice of just using a new mutableStateList I still get the same issue. Seems like maybe something is broken with OutlinedTextField as it reflects the new state (empty string as the label) but has the visual artifact of the gap in the outline the same exact size as the previous items label.
a
yeah I'm still going with my initial thought; something is over-remembering, and I agree with you that it might be in
OutlinedTextField
. Probably worth filing a bug
c
Yay. seems like maybe its not my fault!