Right now, my method of updating my jetpack compose UI on database update is like this:
My Room database holds Player instances (or whatever they're called). This is my PlayerDao:
@Dao
interface PlayerDao {
@Query("SELECT * FROM player")
fun getAll(): Flow<List<Player>>
@Insert
fun insert(player: Player)
@Insert
fun insertAll(vararg players: Player)
@Delete
fun delete(player: Player)
@Query("DELETE FROM player WHERE uid = :uid")
fun delete(uid: Int)
@Query("UPDATE player SET name=:newName where uid=:uid")
fun editName(uid: Int, newName: String)
}
And this is my Player Entity:
@Entity
data class Player(
@PrimaryKey(autoGenerate = true) val uid: Int = 0,
@ColumnInfo(name = "name") val name: String,
)
Lastly, this is my ViewModel:
class MainViewModel(application: Application) : AndroidViewModel(application) {
private val db = AppDatabase.getDatabase(application)
val playerNames = mutableStateListOf<MutableState<String>>()
val playerIds = mutableStateListOf<MutableState<Int>>()
init {
CoroutineScope(Dispatchers.IO).launch {
db.playerDao().getAll().collect {
playerNames.clear()
playerIds.clear()
it.forEach { player ->
playerNames.add(mutableStateOf(player.name))
playerIds.add(mutableStateOf(player.uid))
}
}
}
}
fun addPlayer(name: String) {
CoroutineScope(Dispatchers.IO).launch {
db.playerDao().insert(Player(name = name))
}
}
fun editPlayer(uid: Int, newName: String) {
CoroutineScope(Dispatchers.IO).launch {
db.playerDao().editName(uid, newName)
}
}
}
As you can see, in my ViewHolder init
block, I 'attach' a 'collector' (sorry for my lack of proper terminology) and basically whenever the database emits a new List<Player>
from the Flow
, I re-populate this playerNames
list with new MutableState
s of String
s and the playerIds
list with MutableState
s of Int
s. I do this because then Jetpack Compose gets notified immediately when something changes. Is this really the only good way to go? What I'm trying to achieve is that whenever a change in the player
table occurs, the list of players in the UI of the app gets updated immediately. And also, I would like to access the data about the players without always making new requests to the database. I would like to have a list of Players
at my disposal at all times that I know is updated as soon as the database gets updated. How is this achieved in Android app production?
>` via `.stateIn(viewModelScope)` collected as state in the Composable from the ViewModel