Tuesday, May 12, 2015

Adding context menus to RecyclerView items


Add an affordance

The "three-dot" overflow pattern was my first choice.





Setup click listeners in ViewHolder


        private ImageView mOverflowIcon;

        public FileViewHolder(View holdMe) {
            super(holdMe);
            holdMe.setOnClickListener(this);
            holdMe.setOnLongClickListener(this);
            mOverflowIcon = (ImageView) holdMe.findViewById(R.id.mfp_context_menu);
            mOverflowIcon.setOnClickListener(this);
        }

Create context menu in OnClickListener

Display the PopupMenu. ("this" is the ViewHolder)

        @Override
        public void onClick(View v) {
            if (v == mOverflowIcon) {
                PopupMenu popup = new PopupMenu(v.getContext(), v);
                popup.inflate(R.menu.mfp_overflow_menu_file);
                popup.setOnMenuItemClickListener(this);
                popup.show();
            }
        }

The menu xml.

        <?xml version="1.0" encoding="utf-8"?>
        <menu xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:app="http://schemas.android.com/apk/res-auto">
            <item
                android:id="@+id/delete_file"
                android:title="@string/mfp_delete"
                app:showAsAction="always" />
        </menu>

Add your logic for the menu items

Just the implementation of the OnMenuItemClickListener, and since it's the ViewHolder you have the data as well.

        @Override
        public boolean onMenuItemClick(MenuItem item) {
            Toast.makeText(mOverflowIcon.getContext(),"DO SOME STUFF HERE", Toast.LENGTH_LONG).show();
            return true;
        }

NOTE: WindowLeaked

Just a note, if an orientation change occurs while the PopupMenu is still showing you will get a nice informative WindowLeaked exception. This does not crash your app, it is just poor practice. You need to call popupMenu.dismiss() when the activity context is being destroyed, your resulting code for that may vary depending on your implementation.


16 comments:

  1. how do you know which item you clicked or longClicked on?

    ReplyDelete
    Replies
    1. The function onLongClicked takes a parameter "int position" , which you can use to determine which item it is (position of the clicked item in the array)

      Delete
    2. This is the way to do it using a ListView, not a RecyclerView as demonstrated in this post. You need to manage clicks and long-clicks manually on the views themselves. This can be done in the ViewHolder.

      Delete
  2. how do you know which item you clicked or longClicked on?

    ReplyDelete
    Replies
    1. The ViewHolder is the LongClickListener, so you should have the associated data in scope. e.g. FileViewHolder.this.mFile or just mFile.

      Delete
  3. Your very own commitment to getting the message throughout came to be rather powerful and have consistently enabled employees just like me to arrive at their desired goals.
    java training in marathahalli | java training in btm layout

    java training in jayanagar | java training in electronic city

    java training in chennai | java training in USA

    selenium training in chennai

    ReplyDelete
  4. I simply wanted to write down a quick word to say thanks to you for those wonderful tips and hints you are showing on this site.
    Blueprism training in marathahalli

    Blueprism training in btm

    Blueprism online training

    ReplyDelete
  5. Thank you for allowing me to read it, welcome to the next in a recent article. And thanks for sharing the nice article, keep posting or updating news article.
    Blueprism training in marathahalli

    Blueprism training in btm

    Blueprism online training

    ReplyDelete
  6. Thank you for an additional great post. Exactly where else could anybody get that kind of facts in this kind of a ideal way of writing? I have a presentation next week, and I’m around the appear for this kind of data.

    angularjs Training in chennai
    angularjs Training in chennai

    angularjs-Training in tambaram

    angularjs-Training in sholinganallur

    angularjs-Training in velachery

    ReplyDelete
  7. I am really happy with your blog because your article is very unique and powerful for new reader.
    Click here:
    selenium training in chennai
    selenium training in bangalore
    selenium training in Pune
    selenium training in pune
    Selenium Online Training



    https://michaelrps.blogspot.com/2014/06/c-interface-can-be-inherited.html

    ReplyDelete
  8. I am really impressed with your efforts and really pleased to visit this post.
    Devops Training in Chennai | Devops Training Institute in Chennai

    ReplyDelete
  9. You got an extremely helpful website I actually have been here reading for regarding an hour. I’m an initiate and your success is incredibly a lot of a concept on behalf of me.

    devops online training

    aws online training

    data science with python online training

    data science online training

    rpa online training

    ReplyDelete