I have an app that shows a few fragments (of the same type) in a ViewPager
and I'm having some trouble with context menu items. (I'm using the support library).
When a context menu item is selected in the context menu in one of the fragments, the wrong fragment is receiving the onContextItemSelected
event call.
For example, if I'm on fragment #3 in the pager, the fragment at position #2 receives it instead. If I swipe back to fragment #2, fragment #3 receives the call instead.
I've got a sample here.
(I'm currently working around this in my own app by having a mHandleContext
variable in each fragment and enabling/disabling it when the page is changed. That way the onContextItemSelected
call will go out to all the fragments until the right one is called.)
Am I doing something wrong or is this a bug with the support library? As a side note, this didn't happen when I was using ActionBarSherlock 3.5.1, which had its own fork of the support library.
Oh Google, I mean WTF?
The problem is that onContextItemSelected is very generic, and it is called for each menu item of each fragment.
You can use MenuItem.OnMenuItemClickListener to force fragment menu to not use all onContextItemSelected, but only same function of this fragment.
Use next implementation:
So this is some sort of idiotic design decision by Google or something that has just gone totally unconsidered. The simplest way to work around this is to wrap the
onContextItemSelected
call with an if statement like this:The compatibility library in ActionBarSherlock 3.5 had a hack like this.
It happens because of this:
As you can see, FragmentManager calls Fragment.onContextItemSelected for all of his own fragments until it returns true. In your example I can offer such fix:
Using intent for each of the menu items worked well for me.
The
getUserVisibleHint()
solution doesn't work for me - it always returnstrue
even when the fragment isn't on screen. ThegetGroupId()
solution doesn't work either when inflating the menu from an XML resource, which is my situation.It seems that unless Android changes, any solution is always going to be a bit hacky. I create a global variable to store an ID reference for the current fragment in
onCreateView
. I then pass it to eachContextMenu
MenuItem
inonCreateContextMenu
. When an item is selected, I validate that these two IDs are the same.