Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get context of PopupMenu like ContextMenu

So my ExpandableListView has group rows that are defined like :

group_row.xml

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

    <TextView
        android:id="@+id/GroupName"
        style="@style/ListViewRowStyle"
        android:paddingLeft="40dp"
        android:textSize="18sp" >
    </TextView>

    <ImageView
        android:id="@+id/Menu"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_marginTop="10dp"
        android:contentDescription="@string/default_content_description_text"
        android:src="@drawable/ic_menu_moreoverflow_normal_holo_light" >
    </ImageView>

</RelativeLayout> 

When you click on the TextView it will expand or collapse depending on whether or not the child rows are currently displayed. I have attached an OnClickListener to the ImageView in the group row. When this ImageView is clicked I launch a PopupMenu like the images below :

enter image description here

enter image description here

Once the PopupMenu is displayed and one of the actions is clicked, I would like to perform an action on all children of the group. The problem is that I cannot determine the row in which the ImageView was clicked.

The only way I have figured out how to apply an action to all children is with a ContextMenu like the image below :

enter image description here

I want to avoid using a ContextMenu because a LongClick on a group row may not be obvious for a user to figure out that it would bring up some actions to perform on the children rows. I think the more obvious design is to anchor a PopupMenu to an ImageView (in my case a menu icon) and have the action be applied to the children rows of that group. How can I get this functionality with a PopupMenu ?

like image 725
Etienne Lawlor Avatar asked May 18 '13 05:05

Etienne Lawlor


2 Answers

So I figured out that in order to have some context of which menu icon was clicked, I utilized the setTag() and getTag() methods of the View class and just applied these methods to the ImageView (menu icon).

like image 95
Etienne Lawlor Avatar answered Oct 21 '22 01:10

Etienne Lawlor


You need:

  • A View where to inflate the PopUpMenu (your ImageView)
  • A PopUpMenu saved in res/menu, in this case popup_select_deselect.xml
  • Your own onMenuItemClickListener declared as internal class, in this case onMenuItemClickListener_View

Code:

//TODO initialize rows[]
for (int i = 0; i < rows.lenght; i++){
    //inflate you group_row
    getLayoutInflater().inflate(R.layout.group_row, (ViewGroup)findViewById(R.id.rows_container)); 

   ImageView v_Overflow = (ImageView)findViewById(R.id.Menu);

   //Set onClickListener
   v_Overflow.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    View v_Button = v;
                    PopupMenu pum= new PopupMenu(YourActivity.this, v);

                    //set my own listener giving the View that activates the event onClick (i.e. YOUR ImageView)
                    pum.setOnMenuItemClickListener(new onMenuItemClickListener_View(v) );
                           //inflate your PopUpMenu
                    getMenuInflater().inflate(R.menu.popup_select_deselect, pum.getMenu());
                    pum.show();

                }
            });


    //Update the id of your TextView
    .setId(i); //the i value will be your UNIQUE id for the ImageView

}

The code above is only a static declaration of what your own OnMenuItemClickListener will do.

Pay attention to the given View in the constructor of the following listener. When you create an instance of this listener, the View Id is the same declared in the XML layout. At runtime it will be updated, so when the method onMenuItemClick will be called, the TextView ID is already changed.

Here's the code:

private class onMenuItemClickListener_View implements OnMenuItemClickListener{

    View v_View;

    public onMenuItemClickListener_View(View v){
        v_View=v;
    }

    @Override
    public boolean onMenuItemClick(MenuItem item) {

        int i = v_View.getId();

        switch (item.getItemId()) {
            case R.id.popupItemSelectAll:
                Toast.makeText(YourActivity.this, "Popup Select All for View #: " +  rows[i], Toast.LENGTH_SHORT).show();

                //TODO your code to select all
                return true;
            case R.id.popupItemDeselectAll:
                Toast.makeText(YourActivity.this, "Popup Deselect All for View #: " + rows[i], Toast.LENGTH_SHORT).show();

                //TODO your code to deselect all


            return true;
                default:
                    return false;
            }

        }
    }
}
like image 40
Re MiDa Avatar answered Oct 21 '22 01:10

Re MiDa