In my app, I am trying to add an item to my recycling view. When I add 1 item and call notifyDataSetChanged () there is no problem, only when I want to add a 2nd item and then call the same method the two added items appear 2 times. If I add a 3rd item the 1st added item still appears 2 times the 2nd item now appears 3 times and the 3rd added item also appears 3 times. I'm working with an adapter class for my recyclerview.
I've tried working with NotifyItemInserted(position-1) but it did not work.
Here are some snippets of my code:
My adapter class
class CategoriesAdapter(var clickListener: CategorieListener): ListAdapter<CategorieModel, CategoriesAdapter.CategorieViewHolder>(CategorieDiffCallback()) {
override fun getItemCount(): Int {
return super.getItemCount()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CategorieViewHolder {
return CategorieViewHolder.from(parent)
}
override fun onBindViewHolder(holder: CategorieViewHolder, position: Int) {
val reis = getItem(position)
holder.bind(reis, clickListener, position)
}
class CategorieViewHolder private constructor(val binding: LayoutCategorieItemBinding) : RecyclerView.ViewHolder(binding.root){
fun bind(categorie: CategorieModel, clickListener: CategorieListener, position: Int?){
binding.categorie = categorie
var card = binding.catCard
itemView.setOnClickListener {
clickListener.onClick(categorie, card)
}
itemView.ib_delete.setOnClickListener {
clickListener.onDeleteClick(categorie, position!!)
}
binding.catCard.transitionName = categorie.naam
}
companion object {
fun from(parent:ViewGroup) : CategorieViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
val binding = LayoutCategorieItemBinding.inflate(layoutInflater, parent, false)
return CategorieViewHolder(binding)
}
}
}
class CategorieDiffCallback : DiffUtil.ItemCallback<CategorieModel>() {
override fun areItemsTheSame(oldItem: CategorieModel, newItem: CategorieModel): Boolean {
return oldItem.id == newItem.id
}
override fun areContentsTheSame(oldItem: CategorieModel, newItem: CategorieModel): Boolean {
return oldItem == newItem
}
}
class CategorieListener(val clicklistener: (categorie: CategorieModel, view:MaterialCardView?, position:Int?) -> Unit){
fun onClick(categorie: CategorieModel, view: MaterialCardView) = clicklistener(categorie, view, 0)
fun onDeleteClick(categorie: CategorieModel, position: Int) = clicklistener(categorie, null, position)
}
}
My Fragment behind the scenes
private fun setAdapter() {
val adap = CategoriesAdapter(CategoriesAdapter.CategorieListener{ categorie, cardview, position ->
if(cardview == null){
deleteCategorie(categorie, position!!)
}else{
findNavController().navigate(CategoriesFragmentDirections.actionCategoriesFragmentToItemTakenFragment(categorie.naam,categorie))
}
})
binding.categories.apply {
layoutManager = LinearLayoutManager(this.context)
adapterobj = adap
adapter = adap
}
}
private fun setCardButtons() {
binding.btnAdd.setOnClickListener {
val categorie = CategorieModel(binding.catName.editText?.text.toString(),null,null, userId,0)
newCategorie(categorie)
}
binding.btnCancel.setOnClickListener {
toggleKeyboard()
}
}
private fun newCategorie(cat: CategorieModel){
//Toast.makeText(requireContext(), categories.size.toString(), Toast.LENGTH_SHORT).show()
model.createCategorie(cat)
model.categorieCreate.observe(viewLifecycleOwner, Observer {response ->
response?.let {
if(response.isSuccessful){
afterCreateActions(response.body()?.result)
}else{
afterErrorActions()
}
}
})
}
private fun afterCreateActions(cat: CategorieModel?) {
categories.add(cat!!)
adapterobj.notifyDataSetChanged()
toggleKeyboard()
toggleForm()
Snackbar.make(binding.mainView, "${cat?.naam} werd succesvol toevoegd!", Snackbar.LENGTH_LONG)
.setAnimationMode(Snackbar.ANIMATION_MODE_FADE)
.show()
}