The context menu in Fragment uses a ListView from another fragment: registerForContextMenu (getListView ())

I tried to look for solutions for this, but did not find anything that would fit my situation. I have a MainActivity that extends FragmentActivity and several ListFragments. I use the PagerSlidingTabStrip library for slidetabs and ViewPager. Fragments do not have an XML layout, they are just ListFragments, which returns a ListView, so the layout is not needed.

This is an audio application with a long press on the list item, allowing the user to set the sound file as his ringtone, notification or alarm, or save to the SD card.

Now all the fragments load their data just fine. Everything looks fine, however, when I use the context menu on the Fragment that was loaded in the background, it looks like it uses the ListView from the first or previous fragment that was loaded before it, the one that was visible when it was created.

What I mean, let's say my MainActivity starts, it loads FragmentA, and in the background FragmentB also loads.

The onActivityCreated method uses registerForContextMenu (getListView ()) for both fragments.

@Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); // Data loading etc MyAdapter adapter = new MyAdapter(getActivity(), R.layout.data_row, data); setListAdapter(adapter); registerForContextMenu(getListView()); } 

But it looks like FragmentB is calling registerForContextMenu (getListView ()), and it looks like it is accepting an active Active List ListView, which is a list for FragmentA.

So, let's say I want to save the file from the context menu. I have been clicking on the first FragmentB element for a long time, but it is trying to save the first FragmentA element. If I just touch the list item, it plays its own sound, as expected, but the context menu commands use the list of fragment that was visible when it was preloaded.

Here is onCreateContextMenu. Please note that at this moment it uses the correct item title in the context menu header.

 @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)menuInfo; menu.setHeaderTitle(data.get(info.position).getDataName()); MenuInflater inflater = this.getActivity().getMenuInflater(); inflater.inflate(R.menu.context_menu, menu); } 

And here is the onContextItemSelected.

 @Override public boolean onContextItemSelected(MenuItem item) { AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); int dataID = data.get(info.position).getDataID(); String dataName = data.get(info.position).getDataName(); Activity activity = getActivity(); if(activity instanceof MainActivity) { switch (item.getItemId()){ case R.id.context_ringtone: ((MainActivity) activity).setRingtone(dataID, dataName); return true; case R.id.context_notification: ((MainActivity) activity).setNotification(dataID, dataName); return true; case R.id.context_alarm: ((MainActivity) activity).setAlarm(dataID, dataName); return true; case R.id.context_sd_card: ((MainActivity) activity).saveFile(dataID, dataName); return true; default: return super.onContextItemSelected(item); } } return super.onContextItemSelected(item); } 

Everything works as expected, except that the preloaded fragments use the wrong ListView.

So what I'm looking for is a way to make sure that when loading FragmentB in the background while another fragment is active, FragmentB should register its own ListView for the context menu, and not depending on the type of ListView that occurred to be visible at that time.

I tried using MyFragment.this.getListView (), and I tried using the setUserVisibleHint method, but that didn't help. I tried to make registerForContextMenu (getListView ()) in onResume, hoping it would reregister the correct ListView when the Snippet became active.

Any help would be greatly appreciated, thanks!

+8
android listview android-fragments contextmenu fragment
source share
1 answer

I finally managed to understand this!

It turns out that this is not just a context menu call for an invalid ListView, a context menu was called for ALL fragments.

This was solved using getUserVisibleHint () in the if expression inside the onContextItemSelected method, so if the fragment called by the context menu was not visible, it would return false, but if it was the current visible fragment, it would execute the correct code, i.e., skip fragments that are not the intended fragment. I tried getUserVisibleHint () in a different way, but then I did not think about the problem at right angles.

Here is an example solution.

 @Override public boolean onContextItemSelected(MenuItem item) { if (getUserVisibleHint()) { AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); int dataID = data.get(info.position).getDataID(); String dataName = data.get(info.position).getDataName(); Activity activity = getActivity(); if(activity instanceof MainActivity) { switch (item.getItemId()){ case R.id.context_ringtone: ((MainActivity) activity).setRingtone(dataID, dataName); return true; case R.id.context_notification: ((MainActivity) activity).setNotification(dataID, dataName); return true; case R.id.context_alarm: ((MainActivity) activity).setAlarm(dataID, dataName); return true; case R.id.context_sd_card: ((MainActivity) activity).saveFile(dataID, dataName); return true; default: return super.onContextItemSelected(item); } } } return false; } 
+13
source share

All Articles