MBegemot
08/05/2020, 11:02 AM@Composable
fun startScreen() {
FlowComponent(sflow = myfirstFlow())
}
@Composable
fun FlowComponent(sflow: Flow<String>){
val cnt:String by sflow.collectAsState("")
val sl =state { mutableListOf<String>()}
sl.value.add(cnt)
Box(Modifier.preferredHeight(150.dp)){
sl.value.forEach {
Text(it)
}
}
}
fun myfirstFlow()=flow<String>{
val t=110L
emit("task 1 succeded")
delay(t)
emit("task 2 failed")
delay(t)
emit("task 3 succeded")
delay(t)
emit("task 4 failed")
delay(t)
//emit("uuu"+getNewsPapers(null))
This is a startup screen as I run several functions I intend to emit a string to the flow component that will add it to a list of stings and then write them on screen. And it works but only if I add a certain delay between emits, if the delay is to small or null then I only get the first and last emit. I I'm wrong if i believe that this should work without any delay at all?Zach Klippenstein (he/him) [MOD]
08/05/2020, 4:21 PMcollectAsState
is probably not what you want. For things that are like “state”, it’s typical to conflate values that are emitted one after the other, since any work to be done to render a previous state will be undone or redone to render the subsequent state anyway. The “state” here is the actual list of strings. There are a couple ways you could refactor this:
@Composable
fun FlowComponent(stringFlow: Flow<String>) {
val stringListFlow: Flow<List<String>> = remember(stringFlow) {
stringFlow.scan(emptyList()) { strings, s -> strings + s }
}
val stringList: List<String> by stringListFlow.collectAsState(emptyList())
…
Or
@Composable
fun FlowComponent(stringFlow: Flow<String>) {
var stringList: MutableList<String> by remember { mutableStateOf(emptyList<String>()) }
launchInComposition {
stringFlow.collect { stringList += it }
}
MBegemot
08/05/2020, 4:37 PMZach Klippenstein (he/him) [MOD]
08/05/2020, 4:44 PMMBegemot
08/05/2020, 4:49 PMChuck Jazdzewski [G]
08/05/2020, 4:54 PMscan
above works better for compose because the mutation is done outside of composition and then is presented to compose as an immutable list.MBegemot
08/05/2020, 4:58 PMZach Klippenstein (he/him) [MOD]
08/05/2020, 5:04 PMemit
are you referring to? Compose’s emit
has nothing to do with this really. Also note that “during composition” means done directly inside a Composable function, which is only invoked during an actual composition pass. launchInComposition
(and collectAsState
, which uses launchInComposition
under the hood) launch coroutines that run outside of composition.Zach Klippenstein (he/him) [MOD]
08/05/2020, 5:05 PMsl.value.add(cnt)
in your initial code snippet.Chuck Jazdzewski [G]
08/05/2020, 5:05 PMMBegemot
08/05/2020, 5:23 PMZach Klippenstein (he/him) [MOD]
08/05/2020, 5:30 PMViewModel
or some other non-view-related code. That type would then expose the current UI state via something like a StateFlow<List<String>>
.