https://kotlinlang.org logo
Title
c

Colton Idle

02/27/2022, 11:24 PM
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:
state.list.clear()
state.list.addAll(networkResult.newItems)
to something like this (completely made up api)
state.list.clear().commitTransactionAndWait()
state.list.addAll(networkResult.newItems).commitTransactionAndWait()
For example, if I do this then everything works as expected
state.list.clear()
  viewModelScope.launch { 
      delay(500)
state.list.addAll(networkResult.newItems)
  }
j

jw

02/27/2022, 11:44 PM
Make it a var and create a new mutable state list instead of clearing
c

Colton Idle

02/28/2022, 1:07 AM
Hm. I thought that would work but still encountering the same issue. new code
state.list = mutableStateListOf()
state.list.addAll(networkResult.newItems)
If I do
state.list = mutableStateListOf()
  viewModelScope.launch {
    delay(500)
    state.list.addAll(networkResult.newItems)
  }
then I'm back in business.
e

eygraber

02/28/2022, 2:13 AM
Does it still happen if you make the changes off the main thread?
c

Colton Idle

02/28/2022, 2:14 AM
Hm. How would I do that? Just supply a different dispatchers in the launch method? or do you mean something else?
e

eygraber

02/28/2022, 2:15 AM
Something like:
viewModelScope.launch(Dispatchers.Default) {
  state.list.clear()
  state.list.addAll(networkResult.newItems)
}
a

Adam Powell

02/28/2022, 2:43 AM
what code is reading this list and what behavior are you looking to achieve?
c

Colton Idle

02/28/2022, 2:52 AM
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

Adam Powell

02/28/2022, 3:16 AM
previous item's label?
it sounds like something may be over-remembering somewhere
c

Colton Idle

02/28/2022, 3:52 AM
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

Adam Powell

02/28/2022, 4:03 AM
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

Colton Idle

02/28/2022, 4:04 AM
Yay. seems like maybe its not my fault!