Android Floating Context Menu for ListView/GridView

Hi,

While trying to implement floating context menu, I’ve faced few problems and finally reading through many posts I was able to get it working properly. Here is a sample for implementing it properly-

Suppose lView is your ListView/GridView.

In your onCreate method of activity, do this-

registerForContextMenu(lView);

As given below, you have to override few methods-

@Override
public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.my_context_menu, menu);
}

@Override
public boolean onContextItemSelected(MenuItem item) {
    // below variable info contains clicked item info and it can be null; scroll down to see a fix for it
    AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
    switch(item.getItemId()){
    case R.id.hide:
        hideItem(info.position);
        return true;
    case R.id.info:
        showItemInfo(info.position);
        return true;
    default:
        return super.onContextItemSelected(item);
    }
}

Here is the xml for my_context_menu:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/hide" android:title="Hide" android:showAsAction="always" android:visible="true"></item>
    <item android:id="@+id/info" android:title="Info" android:showAsAction="always" android:visible="true"></item>
</menu>

If you do not want to use xml, you can use below method instead of above on-

@Override
public void onCreateContextMenu(ContextMenu menu, View v,ContextMenu.ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);
    menu.setHeaderTitle("Choose an option");
    menu.add(0, v.getId(), 0, "Hide");
    menu.add(0, v.getId(), 0, "Info");
}

If item.getMenuInfo() is null in onContextItemSelected(MenuItem item) method, I guess you are using custom ListView or GridView instead of android default ones. In such case, your custom View is not implementing getContextMenuInfo() method. Don’t worry we can fix that if you have its source. Open the view file and override the method getContextMenuInfo(). It should look something like this –

    @Override
    protected ContextMenuInfo getContextMenuInfo(){
    	ContextMenuInfo menuInfo = super.getContextMenuInfo();
    	if(menuInfo==null){
    		final ListAdapter adapter = mAdapter;
		final int motionPosition = mPerformClick.mClickMotionPosition;
            if (adapter != null && mItemCount > 0 &&
                    motionPosition != INVALID_POSITION &&
                    motionPosition < adapter.getCount()) {
                final View view = getChildAt(motionPosition);

                if (view != null) {
                    final int clickPosition = motionPosition + mFirstPosition;
                    menuInfo = new AdapterContextMenuInfo(view, clickPosition, adapter.getItemId(clickPosition));
                }
            }
    	}
    	return menuInfo;
    }

Hope this helps!
Cheers!

Leave a comment