torsdag 10 maj 2012

Android : onCreateContextMenu in multiple visible fragments

I've been rewriting my application to support fragments and had a little problem with my context menu as i show two ListView's most of the time. Missed the information at Android Developer homepage.

Note: Although your fragment receives an on-item-selected callback for each menu item it adds, the activity is first to receive the respective callback when the user selects a menu item. If the activity's implementation of the on-item-selected callback does not handle the selected item, then the event is passed to the fragment's callback. This is true for the Options Menu and context menus.

And it' doesnt go directly to the fragment that was pressed, it goes from first created to last created.
I handle them in each fragment so we need to know how which one was orginating the call.

public class FragmentCategories extends Fragment {
    static final int FRAGMENT_GROUPID = 30;
    static final int MENU_EDIT = 1;
    static final int MENU_REMOVE = 2;

   @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuinfo)
    {
        super.onCreateContextMenu(menu, v, menuinfo);
        menu.add(FRAGMENT_GROUPID, MENU_EDIT, Menu.NONE, "Edit");
        menu.add(FRAGMENT_GROUPID, MENU_REMOVE, Menu.NONE, "Remove);
        AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)menuinfo;
    }
    @Override
    public boolean onContextItemSelected(MenuItem item)
    {
       // Set a different FRAGMENT_GROUPID on each fragment.
       // A simple check, only continues on the correct fragment.
        if(item.getGroupId() == FRAGMENT_GROUPID)
        {
            AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
            selectedCategory = (BudgetCategory) cListView.getItemAtPosition(info.position);
            switch (item.getItemId())
            {
                case MENU_EDIT:
                    // Do something!
                    return true;
                case MENU_REMOVE:
                    // Do something!
                    return true;
            }
        }
        // Be sure to return false or super's so it will proceed to the next fragment!
        return super.onContextItemSelected(item);
    }


Simply set a unique identifier in each fragment and create the menu with the the identifier as groupID.
The callback will fall through until we hit the fragment that made the call.

public abstract MenuItem add(int groupId, int itemId, int order, int titleRes)
  Parameters
    groupId    The group identifier that this item should be part of. 
               This can also be used to define groups of items for batch state changes.
               Normally use NONE if an item should not be in a group.
    itemId     Unique item ID. Use NONE if you do not need a unique ID.
    order      The order for the item. 
               Use NONE if you do not care about the order. See getOrder().
    titleRes   Resource identifier of title string.