How would you handle a not showing a progress bar ...
# compose
c
How would you handle a not showing a progress bar until like 300ms has gone by? I have a single state being emitted and it currently has isLoaded and my animated visibility uses that to fade between a loading spinner and the content. Would I add a third state of like isLoadedButThresholdNotMet?
d
What i did was to configure the animationSpec of the enter animation of AnimatedVisibilty to use tween with a delay
c
Oooh. So basically build a delay into the progress bar via animated visibility. Hmmm 🤔
d
You pretty much have two options here: 1) Achieve that delay via animation delay, 2) manage the delayed state change outside of animation, which is useful when the delayed state change affects multiple components. It's important to consider the "interruption" case: during this delay, could there be another state change (e.g. some form of dismiss or cancel) that could cause the progress bar to never show? AnimatedVisibility can handle that just fine, as it's effectively an interruption to the delayed animation. But if you were to launch a coroutine to achieve that delayed showing, you'll need to make sure the job is canceled when you decide to not show at all for various reasons.
LaunchedEffect
could be helpful for automatically canceling the old job:
Copy code
var showProgressBar by remember { mutableStateOf(false) }
var isLoaded by remember { mutableStateOf(false) }
LaunchedEffect(isLoaded) {
   if (isLoaded) { 
        launch {
            delay(300)
            showProgressBar = true 
       } 
   } else {
      showProgressBar = false
   }
}
z
For simple cases you could even use
produceState
I think:
Copy code
var isLoaded by remember { mutableStateOf(false) }
val showProgressBar by produceState(initialValue = false, key1 = isLoaded) {
  if (isLoaded) {
    delay(300)
    value = true
  } else {
    value = false
  }
}
d
Once upon a time I created an Rx operator to help automatically handle this in a reactive manner. It works if your view states are represented by a stream. And then I wrote a blog post describing this approach. Not sure how it aged, it worked nicely for me back then: https://blog.usejournal.com/reactive-approach-to-removing-flicker-between-loading-and-content-ui-states-73f1ad240097