1

I am facing an issue where a change in an item is not reflected when using submitList in ListAdapter.

I know that below code works in case I want to remove an item when using ListAdapter as inside submitList the framework checks whether lists are similar. It is also demonstrated in this sample from one of the developers working at Google https://github.com/android/views-widgets-samples/blob/main/RecyclerViewKotlin/app/src/main/java/com/example/recyclersample/data/DataSource.kt

fun removeItem(position: Int)
{
  val copiedList = adapter.currentList.toMutableList()
  copiedList.removeAt(position)
  adapter.submitList(copiedList)
} 

The problem is when you want to change something using same method it won't work because toMutableList() creates a shallow copy of the list.

and thus when I do this,

fun changeItemAtPositionWith(isEnabled: Boolean, position: Int) {
  val copiedList = adapter.currentList.toMutableList()
  copiedList[position].isEnabled = !copiedList[position].isEnabled
  adapter.submitList(copiedList)
}

It doesn't work because content of both lists (copied and non-copied) refer to the same items and while comparing ListAdapter doesn't find any change.

I don't think creating deep copy for every change is a good idea at all.

nayan dhabarde
  • 1,734
  • 1
  • 19
  • 38
  • Can you share your isContentTheSame and areItemsTheSame functions? – sanket vetkoli Feb 10 '22 at 07:55
  • areItemsTheSame returns olditem.id == newItem.id isContentTheSame returns olditem == new item I am using a data class – nayan dhabarde Feb 12 '22 at 10:03
  • Ok and is isEnabled part of your data class constructor? What I am guessing is isEnabled is not part of your equals function hence isContentTheSame is returning true even when you are changing the isEnabled flag. Can you post your data class as well please – sanket vetkoli Feb 12 '22 at 15:27
  • Did you use `ViewModel` or `LiveData` or `StateFlow` in your project? – Sam Chen Feb 22 '22 at 15:11
  • I have used ViewModel and Live data, But I think this question is independent of it. You can see the smallest reporducible scenario is to just use a list, adapter, diffutil.itemcallback and recycler view – nayan dhabarde Feb 28 '22 at 06:00

1 Answers1

0

The only way I could solve it was to copy the object which has to be updated as shown below:

fun updateItemAtPosition(cheeseType, position) {
   val newPizza = pizzas[position].copy(cheese = cheeseType)
   pizzas[position] = newPizza
   adapter.submitAndUpdateList(pizzas)
}

And here is what submitAndUpdateList does

fun submitAndUpdateList(list: List<Pizza>) {
   submitList(list.toMutableList())
}

Here is the link to GitHub project, you can try running the app https://github.com/ndhabrde11/ListAdapter-Sample/blob/master/app/src/main/java/com/example/listadaptertest/PizzaAdapter.kt

nayan dhabarde
  • 1,734
  • 1
  • 19
  • 38