A list gets populated with data from a Room (sqlite) db.
By following tutorials and examples, mostly from Android itself, I came up with the following layered architecture:
// --- database dao layer ---
@Entity (...)
data class Data(...)
@Query("SELECT * FROM ... where ...")
fun getData(...): Flow<List<Data>>
// --- repository ---
fun getDataStream(...): Flow<List<Data>> = dao.getData(...)
// --- viewModel ---
sealed interface SomeUiState {
data object Loading: SomeUiState
data class Loaded(val dataList: List<Data>,...): SomeUiState
}
class SomeViewModel(repository, ...) : ViewModel() {
val uiState: StateFlow<SomeUiState> = repository.getDataStream(...)
.map { data ->
SomeUiState.Loaded(data,...)
}.stateIn(
scope = viewModelScope,
initialValue = SomeUiState.Loading,
started = SharingStarted.WhileSubscribed(stopTimeoutMillis = 5000)
)
fun addNewData(...) {
val newData = SomeData(...)
viewModelScope.launch {
repository.insertData(newData)
}
}
}
// --- UI ---
@Composable
fun StatefullScreen(viewModel: SomeViewModel = viewModel()) {
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
StatelessScreen(uiState)
}
@Composable
fun StatelessScreen(uiState: SomeUiState) {
val listItems = mutableListOf<PreparedListItem>()
uiState.dataList.map {
// Preparing the actual list items
// Should I ideally do this in the uiState? I guess it's not relevant.
}.toCollection(listItems)
TheListComposable(listItems, modifier...)
}
The list gets displayed on the screen, the insert of new data works…but how do I update the list on the screen after an insert? Do I need to trigger the uiState flow somehow?