LazyColumn notify about modification of item
Asked Answered
W

2

3

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)
}
Wedged answered 12/9, 2021 at 0:13 Comment(7)
why your TextField only has a single parameter, is is read only? Show readAllData and how you modify the dataGala
1. my mistake, there are no textFields, I meant Text 2. I will update the post with info about readAllData and modificationWedged
I still have no idea how your xViewModel connected to repository.readAllData, and why it should trigger recompositionGala
basically the only thing I'm trying to do is "refresh" the list that contains all the info about xEntities after one of the entities is modifiedWedged
From the compose point of view you're doing all right, look for why your readAllData doesn't update LiveData value after database updateGala
listData is initialised at the beginning of the composable function and I would need to probably "refresh" it's value (it changes when I add/delete new Entity but not on modification)Wedged
Yes, check out this answerGala
D
1

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

Douty answered 23/6, 2022 at 3:15 Comment(0)
L
0

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.

Lidda answered 12/9, 2021 at 9:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.