I am developing a app using jetpack compose, and I am new to this UI framework, I want to display the categories amountSpent property. I am changing the amount spend in dialog and want to reflect the change in list, Here issue is the Lazy Column does not recompose but Text inside categories forloop works. I am not sure why Lazy Column is not working but simple forloop is working

          var categories = remember {
            mutableStateListOf(
              Category.FoodCategory(amountSpent=100),
              Category.ShoppingCategory(amountSpent=50),
              Category.TransportationCategory(amountSpent=80),
              Category.EducationCategory(amountSpent=90)
            )
          }

categories[0].amountSpent=400
@Composable
fun HomeUi(categories: SnapshotStateList<Category>) {
         
LazyColumn() {
items(categories){
  Text(text = it.amountSpent.toString())
   }
}
categories.forEach{
  Text(text = it.amountSpent.toString())
}
}

I was expecting that Lazy Column and ForEach world result the same but to my shock Lazy Column did not work

The Output was
Before 
100
50
90
80
100
50
90
80

After Change
100
50
90
80
400
50
90
80

Code for category:

sealed class Category(
  val name: String,
  val totalBudget:Int,
  open var amountSpent: Int,
  @DrawableRes val icon : Int){
  data class FoodCategory(override var amountSpent: Int=0):
    Category("Food",500,amountSpent,R.drawable.ic_food)
  class ShoppingCategory(override var amountSpent: Int=0):
    Category("Shopping",500,0,R.drawable.ic_shopping)
  class TransportationCategory(override var amountSpent: Int=0):
    Category("Transportation",500,amountSpent,R.drawable.ic_transportation)
  class EducationCategory(override var amountSpent: Int=0):
    Category("Education",500,amountSpent,R.drawable.ic_education)

}

Edit Fixed the Issue: I had to remove the category form list and add it again so that the lazy column re-compiles, assigning value to it does not work,

Please can anyone explain if is this a bug from Jetpack compose or an issue from my side?

var categoryChanged = categories.find { cat == it.name }
                  categoryChanged?.amountSpent = categoryChanged?.amountSpent?.plus(400)!!
                  var ind = categories.indexOf(categoryChanged)
                  categories.remove(categoryChanged)
                  categories.add(ind, categoryChanged!!)

1

There are 1 best solutions below

1
On

if you need a change item position or update value in list and you want to recomposition in LazyColumn, you have to add key.

LazyColumn {
    items(
        items = messages,
        key = { message ->
            // Return a stable + unique key for the item
            message.id
        }
    ) { message ->
        MessageRow(message)
    }
}