0

I am trying to create a popup menu on my recycler view item which is in a fragment. The menu should be created once the user clicks on the 3 dots on my recycler view item here is my code for the adapter class:

class ExampleAdapter(context: Context, exampleList : ArrayList<Stream>) : RecyclerView.Adapter<ExampleAdapter.ViewHolder>() {

var mContext: Context = context
var favorites = exampleList

private var inflator: LayoutInflater? = LayoutInflater.from(context)

override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder {
    val view = inflator?.inflate(R.layout.favorites_list_item_layout, parent, false)
    return ViewHolder(view)
}

override fun getItemCount(): Int {
    return favorites.size
}

override fun onBindViewHolder(holder: ViewHolder?, position: Int) {
    val st = favorites.get(position)
    Picasso.with(mContext).load(favorites.get(position).image).into(holder?.stImage)
    holder?.sName?.text = st.name
    holder?.bind(st)
    holder?.deleteOption?.setOnClickListener(View.OnClickListener {

        var popup  = PopupMenu(mContext, holder.deleteOption!!)

        popup.setOnMenuItemClickListener { item: MenuItem? ->

            when (item!!.itemId) {
                R.id.delete -> {
                    Toast.makeText(mContext, "Showing Toast!", Toast.LENGTH_LONG).show()
                     true
                }
                else ->false
            }

        }
        popup.menuInflater.inflate(R.menu.favorite_menu,popup.menu)
        try {
            val fieldMPopup = PopupMenu::class.java.getDeclaredField("mPopup")
            fieldMPopup.isAccessible = true
            val mPopup = fieldMPopup.get(popup)
            mPopup.javaClass
                    .getDeclaredMethod("setForceShowIcon", Boolean::class.java)
                    .invoke(mPopup, true)
        } catch (e: Exception){
            Log.e("Main", "Error showing menu icons.", e)
        } finally {
            popup.show()
        }
    })

}

And the context which I pass is from the fragment and I created the context this way context = activity.applicationContext and my error/exception looks like this:

E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.app, PID: 9724 android.view.InflateException: Binary XML file line #17: Failed to resolve attribute at index 6: TypedValue{t=0x1d/d=0xffff4081 a=3 r=0x7f060035}

The exception is thrown at popup.show().

Here is my favorite_menu code

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

<item
    android:id="@+id/delete"
    android:title="@string/delete" />
</menu>

here is my code for favorites_list_item_layout

    <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">


        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/five">

            <de.hdodenhof.circleimageview.CircleImageView xmlns:app="http://schemas.android.com/apk/res-auto"
                android:id="@+id/station_image"
                android:layout_width="70dp"
                android:layout_height="70dp"
                app:civ_border_width="@dimen/zero" />

            <TextView
                android:id="@+id/stations_stream_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentStart="true"
                android:layout_centerVertical="true"
                android:layout_marginStart="@dimen/hundred_three"
                android:text="Station Name"
                android:textColor="@color/white_color"
                android:textSize="@dimen/twenty"
                android:textStyle="bold"
                android:layout_alignParentLeft="true"
                android:layout_marginLeft="103dp" />


            <TextView
                android:id="@+id/delete_options"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentEnd="true"
                android:layout_centerVertical="true"
                android:layout_marginEnd="@dimen/thirteen"
                android:paddingLeft="@dimen/activity_horizontal_margin"
                android:text="&#8942;"
                android:textColor="@color/white_color"
                android:textAppearance="?android:textAppearanceLarge"
                android:layout_alignParentRight="true"
                android:layout_marginRight="@dimen/thirteen" />

        </RelativeLayout>


</LinearLayout>

This is my ViewHolder class code

 inner class ViewHolder(favoriteView: View?) : RecyclerView.ViewHolder(favoriteView) {

    val view = favoriteView
    var stationImage: CircleImageView? = null
    var stationName: TextView? = null
    var deleteOption : TextView? = null

    init {
        stationImage = view?.findViewById<CircleImageView>(R.id.station_image)
        stationName = view?.findViewById<TextView>(R.id.stations_stream_name)
        deleteOption = view?.findViewById(R.id.delete_options)

    }
vinay kumar
  • 555
  • 1
  • 6
  • 16

1 Answers1

0

You would better Create an interface first. initialise it in your activity/ fragment and inject it to your adapter. then pass it to your view holder and inside View.OnclickListener block of the view holder . you call on click method of your interface. after that you take action on your fragment/ activity easily.

//1. Create Interface

            public interface RVListener {

            void onClick(View view, int position);}

//2. initialise your listener inside your fragment/activity

     private RVListener listener = (view, position) -> {
        // open your popup menu or ...
     };

//3.pass "listener" to the adapter

   MyAdapter adapter = new MyAdapter(data,listener);

//4. inside your adapter assign the variable and pass it to view holder

public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

        private RVListener listener;
        private List<Data> data = new ArrayList<>();

        MyAdapter(List<Data> data, RVListener listener) {
            this.listener = listener;
            this.data = data;
        }

         @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            Context context = parent.getContext();
            View v = LayoutInflater.from(context).inflate(R.layout.my_layout, parent, false);
            return new RowViewHolder(v, listener);
        }
}

//5. handle Click inside your viewHolder
public class RowViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    private RVListener listener;

    RowViewHolder(View v, RecyclerViewClickListener listener) {
        super(v);
        this.listener = listener;
        v.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        listener.onClick(view, getAdapterPosition());
    }
}

After you do this . you definitely have Context to do your popup . hope it helps.