0

I have a recyclerview, and each item in the list has a popup menu allowing the user to duplicate or delete the item. My recyclerview also includes an itemTouch helper to rearrange the item order.

My problem is the following: when an item is duplicated or deleted, I want to notify the recyclerview's adapter (adapter.notifyItemRemoved(position:Int)). But the popup menu is defined in my viewholder. So can I notify the adapter?

In my fragment

        myViewModel.aList.observe(viewLifecycleOwner) {
            val myAdapter = MyAdapter(it, this)
            
            // simpleCallback defined here. Removed for clarity.

            val itemTouchHelper = ItemTouchHelper(simpleCallback)
            itemTouchHelper.attachToRecyclerView(binding.myRecyclerView)


            binding.myRecyclerView.apply {
                layoutManager = LinearLayoutManager(activity)
                adapter = theAdapter
              }

        }

    }

My adapter

class myAdapter (
    private val aList:List<myItem>,
    private val clickListener: myClickListener,

    ): RecyclerView.Adapter<itemViewHolder>(), ItemTouchHelperAdapter {

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): itemViewHolder{
            val from = LayoutInflater.from(parent.context)
            val binding = myCellBinding.inflate(from, parent, false)
            return itemViewHolder(parent.context, binding,clickListener)
        }

        override fun onBindViewHolder(holder: myViewHolder, position: Int) {
            holder.bindItem(aList[position])
        }

        override fun getItemCount(): Int = aList.size

}

The viewHolder

class myViewHolder (
    private val context: Context,
    private val binding: myCellBinding,
    private val clickListener: ItemClickListener

    ) : RecyclerView.ViewHolder(binding.root) {


        fun bindItem(item: Item){
            
          // other stuff, removed for clarity

          popupMenu(item)

        }


    private fun popupMenu(item: Item){

        val popupMenu = PopupMenu(context,binding.anOptionsMenuButton)
        popupMenu.inflate(R.menu.a_menu)
        popupMenu.setOnMenuItemClickListener {
            when(it.itemId){
                R.id.duplicateItemOption -> {

                   **// DUPLICATE THE ITEM
                   // HOW TO NOTIFY THE ADAPTER THAT AN ITEM HAS BEEN ADDED?**

                    true
                }
                R.id.deleteItemOption -> {

                    **// DELETETHE ITEM
                   // HOW TO NOTIFY THE ADAPTER THAT AN ITEM HAS BEEN REMOVED?**

                    true
                }
                else -> true
            }
        }


        binding.anOptionsMenuButton.setOnClickListener{

            try {
                val popup = PopupMenu::class.java.getDeclaredField("mPopup")
                popup.isAccessible = true
                val menu = popup.get(popupMenu)
                menu.javaClass
                    .getDeclaredMethod("setForceShowIcon", Boolean::class.java)
                    .invoke(menu, true)
            }catch (e:Exception) {
                e.printStackTrace()
            }finally {
                popupMenu.show()
            }

            true
        }
    }





    }

How to notify the recyclerview adapter (in my fragment) that items have been removed/added when action is executed in the viewHolder popup menu (popupMenu.setOnMenuItemClickListener)? Thanks!

jaywalker
  • 1
  • 1
  • Define your ViewHolder as an `inner class` inside the adapter so it can call the adapter’s functions. But you might want to look into using ListAdapter. – Tenfour04 Apr 01 '23 at 03:00

0 Answers0