Hey I am using diff util with ListAdapter. The updating of list works but I can only see those new values by scrolling the list, I need to view the updates even without recycling the view (when scrolling) just like notifyItemChanged(). I tried everything inside this answer ListAdapter not updating item in RecyclerView only working for me is notifyItemChanged or setting adapter again. I am adding some code. Please someone know how to fix this problem?
Data and Enum class
data class GroupKey(
val type: Type,
val abc: Abc? = null,
val closeAt: String? = null
)
data class Group(
val key: GroupKey,
val value: MutableList<Item?> = ArrayDeque()
)
enum class Type{
ONE,
TWO
}
data class Abc(
val qq: String? = null,
val bb: String? = null,
val rr: RType? = null,
val id: String? = null
)
data class RType(
val id: String? = null,
val name: String? = null
)
data class Item(
val text: String? = null,
var abc: Abc? = null,
val rr: rType? = null,
val id: String? = null
)
viewmodel.kt
var list: MutableLiveData<MutableList<Group>?> = MutableLiveData(ArrayDeque())
fun populateList(){
// logic to call api
list.postValue(data)
}
fun addItemTop(){
// logic to add item on top
list.postValue(data)
}
inside view model I am filling data by api call inside viewmodel function and return value to list. Also another function which item is inserting at top of list so that's why is used ArrayDeque
Now I am adding nested reyclerview diff util callback.
FirstAdapter.kt
class FirstAdapter :
ListAdapter<Group, RecyclerView.ViewHolder>(comp) {
companion object {
private val comp = object : DiffUtil.ItemCallback<Group>() {
override fun areItemsTheSame(oldItem: Group, newItem: Group): Boolean {
return oldItem == newItem
}
override fun areContentsTheSame(oldItem: Group, newItem: Group): Boolean {
return ((oldItem.value == newItem.value) && (oldItem.key == newItem.key))
}
}
}
......... more function of adapter
}
FirstViewHolder
val adapter = SecondAdapter()
binding.recyclerView.adapter = adapter
adapter.submitList(item.value)
SecondAdapter.kt
class SecondAdapter : ListAdapter<Item, OutgoingMessagesViewHolder>(comp) {
companion object {
private val comp = object : DiffUtil.ItemCallback<Item>() {
override fun areItemsTheSame(oldItem: Item, newItem: Item): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: Item, newItem: Item): Boolean {
return ((oldItem.rr == newItem.rr) &&
(oldItem.text == oldItem.text) && (oldItem.abc == newItem.abc))
}
}
}
..... more function
}
Activity.kt
viewModel.list.observe(this, { value ->
submitList(value)
})
private fun submitList(list: MutableList<Group>?) {
adapter?.submitList(list)
// adapter?.notifyDataSetChanged()
}
I am 100% sure that my list is updating and my observer is calling when my new list is added. I debug that through debug view. But problem is I can only see those new values by scrolling the list, I need to view the updates even without recycling the view (when scrolling) just like notifyItemChanged()
UPDATE
viewmodel.kt
class viewModel : BaseViewModel(){
var list: MutableLiveData<MutableList<Group>?> = MutableLiveData()
//... more variables...
fun fetchData(context: Context) {
viewModelScope.launch {
val response = retroitApiCall()
response.handleResult(
onSuccess = { response ->
list.postValue(GroupData(response?.items, context))
},
onError = { error ->
Log.e("error" ,"$error")
}
)
}
}
}
internal fun GroupData(items: List<CItem>?, context: Context): MutableList<Group> {
val result: MutableList<Group> = MutableList()
items?.iterator()?.forEach { item ->
// adding item in list by add function and then return list.
return result
}
private fun addItemOnTop(text: String) {
list.value?.let { oldlist ->
// logic to add items on top of oldlist variable
if(top != null){
oldlist.add(0,item)
}else{
val firstGroup = oldlist[0]
firstGroup.value.add(item)
}
list.postValue(oldlist)
}
}
}
I am using sealed class something like this but not this one Example. And Something similar to these when call api Retrofit Example. Both link I am giving you example. What I am using in my viewmodel.