Zoff
01/09/2024, 12:52 PMAlexander Maryanovsky
01/09/2024, 1:16 PMAlexander Maryanovsky
01/09/2024, 1:16 PMCasey Brooks
01/09/2024, 1:56 PM@Composable
fun DataList(data: List<String>) {
// using LazyColumn
LazyColumn {
items(data) { item ->
DataListItem(item)
}
}
// using for-loop
data.forEach { item ->
DataListItem(item)
}
}
@Composable
fun DataListItem(data: String) {
// ...
}
RecyclerView required a bunch of extra boilerplate and special handling of the data because the View system is not natively designed to render UI based on data like that. But Compose is already designed to make the UI purely a function of data, so the optimization of LazyColumn is just that: an optimization. Use it when it makes sense, semantically, which is when you’re rendering a large list of data.Zoff
01/09/2024, 3:45 PMAlexander Maryanovsky
01/09/2024, 3:46 PMAlexander Maryanovsky
01/09/2024, 3:46 PMAlexander Maryanovsky
01/09/2024, 3:46 PMZoff
01/09/2024, 3:54 PMAlexander Maryanovsky
01/09/2024, 3:54 PMZoff
01/09/2024, 3:59 PMZoff
01/09/2024, 4:00 PMAlexander Maryanovsky
01/09/2024, 4:01 PMvar progress by mutableStateOf(0)
@OptIn(DelicateCoroutinesApi::class)
fun main() {
GlobalScope.launch {
while (progress < 100) {
delay(100)
progress += 1
}
}
singleWindowApplication {
LazyColumn(Modifier.width(400.dp).fillMaxHeight()) {
item {
MyProgressBar()
}
items(1000) {
Text(it.toString(), Modifier.padding(16.dp))
}
}
}
}
@Composable
fun MyProgressBar() {
Text("${progress}%")
}
Casey Brooks
01/09/2024, 4:01 PMmutableStateOf()
with a LazyColumn
, and then replace that list with one containing the changed value (or hold the list with mutableStateListOf()
and use its functions to update the list). If the performance there si good, try increasing the size of the list to see where (or if) if breaks downZoff
01/09/2024, 4:19 PMZoff
01/09/2024, 4:20 PMval messagestore = CoroutineScope(SupervisorJob()).createMessageStore()
because it does what i want. but i have not idea what that actually meansCasey Brooks
01/09/2024, 4:24 PMmutableStateListOf()
. That’s used for the case where you are updating a list’s content purely from Compose and not in a ViewModel.
Apart from that, mutableStateOf()
is how Compose knows when to recompose. It should hold an immutable value, and when that value is replaced, Compose will recompose and update the relevant parts of the UI. This process is smart and will skip anything that has not changed, and this includes if only a single property of an object has changed.
collectAsState()
adapts a StateFlow
to Compose by literally just collecting the flow and updating a mutableStateOf()
variable for you.Casey Brooks
01/09/2024, 4:29 PMCoroutineScope.createStore()
is not @Composable
, it basically means that the store it creates lives outside of Compose. You can use any CoroutineScope you have to create and manage the store. This can be tied to a custom global CoroutineScope in Desktop, viewModelScope
or lifecycleScope
in an Android Fragment, or even rememberLifecycleScope()
to tie it to a specific Composable function.
Whatever scope is used to create the store will determine when that store is active. If the associated coroutineScope is cancelled, the store will be closed and it will no longer process new values. But it lives on its own outside of Compose, and is only tied to compose when you collect its stateFlow using mesageStore.stateFlow.collectAsState()
Zoff
01/09/2024, 5:59 PMZoff
01/09/2024, 5:59 PM