0

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()
    }

Gif of how it looks

  • do update your question and paste the codes directly in the question. (instead of pictures of the codes) – Angel Koh Feb 07 '21 at 12:14

1 Answers1

0

The problem was that I was Observing liveData in an clicklistener, that was the main problem! Thanks to Ramakrishna Joshi n!

Visit answer!