Reputation: 3015
I have a composable function that looks something like this:
@Composable
fun listScreen(context: Context, owner: ViewModelStoreOwner) {
val repository = xRepository(getAppDatabase(context).xDao()
val listData by repository.readAllData.observeAsState(emptyList())
// repository.readAllData returns LiveData<List<xEntity>>
// listData is a List<xEntity>
LazyColumn(){
items(listData.size) {
Card {
Text(listData[it].name)
Text(listData[it].hoursLeft.toString())
Button(onClick = {updateInDatabase(owner, name = listData[it], hoursLeft = 12)}) {...}
}
}
}
}
fun updateInDatabase(owner: ViewModelStoreOwner, name: String, hoursLeft: Int) {
val xViewModel....
val newEntity = xEntity(name=name, hoursLeft = Int)
xViewModel.update(newEntity)
}
and as you propably can guess, the LazyColumn doesn't refresh after modification of entity, is there a way to update listData after every update of entity?
edit:
class xRepository(private val xDatabaseDao) {
val readAllData: LiveData<List<xEntity>> = xDatabaseDao.getallXinfo()
...
suspend fun updatePlant(x: xEntity) {
plantzDao.updateX(x)
}
}
interface xDatabaseDao {
@Query("SELECT * FROM xInfo ORDER BY id DESC")
fun getAllXInfo(): LiveData<List<xEntity>>
....
@Update(onConflict = OnConflictStrategy.REPLACE)
suspend fun updateX(x: xEntity?)
}
modification of entity:
fun updatePlantInDatabase(owner: ViewModelStoreOwner, name: String, waterAtHour: Int, selectedDays: ArrayList<Int>) {
val xViewModel: xViewModel = ViewModelProvider(owner).get(xViewModel::class.java)
val new = xEntity(name = name, waterAtHour = waterAtHour, selectedDays = selectedDays)
xViewModel.updatePlant(new)
}
Upvotes: 3
Views: 4056
Reputation: 21
I use mutableStateOf
to wrap fields that need to recomposed. Such as
class TestColumnEntity(
val id: String,
title: String = ""
){
var title: String by mutableStateOf(title)
}
View:
setContent {
val mData = mutableStateListOf(
TestColumnEntity("id_0").apply { title = "cnm"},
TestColumnEntity("id_1").apply { title = "cnm"},
TestColumnEntity("id_2").apply { title = "cnm"},
TestColumnEntity("id_3").apply { title = "cnm"},
TestColumnEntity("id_4").apply { title = "cnm"},
TestColumnEntity("id_5").apply { title = "cnm"},
)
Column {
Button(onClick = {
mData.add(TestColumnEntity("id_${Random.nextInt(100) + 6}").apply { title = "ccnm" })
}) {
Text(text = "add data")
}
Button(onClick = {
mData[1].title = "test_${Random.nextInt(100)}"
}) {
Text(text = "update data")
}
TestLazyColumn(data = mData, key = {index, item ->
item.id
}) {
Text(text = it.title)
}
}
}
It works in my testcase
Upvotes: 1
Reputation: 1378
If you want to update lazy column (say recompose in jetpack compose) so use side effects. Put list getting function in side effect (Launch Effect or other side effects) when list is change side effect automatic recompose your function and show updated list.
Upvotes: 0