Hasan A Yousef
Hasan A Yousef

Reputation: 24988

Android recycleview is duplicating upon data update

In MainActivity, I've:

lateinit var adapter: ChapterAdapter
class MainActivity : AppCompatActivity() {
   userViewModel = ViewModelProviders.of(this).get(UserViewModel::class.java)

   userViewModel.allUsers.observe(this, Observer { users ->
       users?.let { it ->
             it?.forEach {
                 val insertIndex = chaptersList.size
                 chaptersList.add(insertIndex, it.toString())
                 adapter.notifyItemInserted(insertIndex)
             }
         }
   })
}

In the chapterAdapter, I've:

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    holder.checkBox.setOnCheckedChangeListener { _, b ->
            Toast.makeText(context, b.toString(), 
    Toast.LENGTH_LONG).show()
            userViewModel.update(position, "AHasan")
          //  adapter.notifyDataSetChanged()
            adapter.notifyItemChanged(position)

    }
}

My repository is:

import androidx.annotation.WorkerThread
import androidx.lifecycle.LiveData

class UserRepository(private val userDao: UserDao) {

    val allUsers: LiveData<List<User>> = userDao.getAll()

    @WorkerThread
    fun insert(user: User) {
        userDao.insertAll(user)
    }

    @WorkerThread
    fun update(id: Int, name: String) {
        userDao.updateById(id, name)
    }
}

The recycleView is updating correctly upon insert, but upon ItemChanged it is duplicating everything, i.e. all the cards in the recycleView, if I closed the app, and run it again, things are back to the correct situation

Upvotes: 0

Views: 311

Answers (1)

a_local_nobody
a_local_nobody

Reputation: 8191

if i had to guess why this happens, i'd say that your userViewModel.update(position, "AHasan") is updating this observer :

 userViewModel.allUsers.observe(this, Observer { users ->
       users?.let { it ->
             it?.forEach {
                 val insertIndex = chaptersList.size
                 chaptersList.add(insertIndex, it.toString())
                 adapter.notifyItemInserted(insertIndex)
             }
         }
   })

and then all the items are added again. so, as a suggestion and possible fix, try clearing your list here:

 userViewModel.allUsers.observe(this, Observer { users ->
       users?.let { it ->
     //try clearing the adapters items here before adding them again
     //as John Joe said you can use 
        chaptersList.clear()
     // try updating your adapter here
        adapter.notifyDataSetChanged()
             it?.forEach {
                 val insertIndex = chaptersList.size
                 chaptersList.add(insertIndex, it.toString())
                 adapter.notifyItemInserted(insertIndex)
             }
         }
   })

Upvotes: 1

Related Questions