My app has a ListView
and I'm using a Contextual Action Bar
for devices above SDK 11 and the old popup contextual actions for older devices. I know there's a way to use a CAB with older devices but I tried to implement it and found it wasn't worth the effort for devices that will eventually be obsolete. I know it's some code duplication, but, in theory, I will be getting rid of the old popup actions (emphasis on "in theory").
Anyhow, when I use the emulator, the CAB works fine, but the old popup actions for older devices seems to hit onContextItemSelected
twice when I put a breakpoint in that event. I've just start implement a ViewPager
for my app and this wasn't happening before the ViewPager
so not sure if that is causing the issue.
This is the code I'm using:
public class MyFragment extends SherlockListFragment
{
private ListView mListView;
private android.view.ActionMode mActionMode;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
@Override
public void onCreateContextMenu(final ContextMenu menu, final View v, final ContextMenuInfo menuInfo)
{
super.onCreateContextMenu(menu, v, menuInfo);
if (this.mActionMode != null) return;
menu.add(1, 0, 0, "Delete");
menu.add(1, 1, 0, "Save");
}
@Override
public void onActivityCreated(final Bundle icicle)
{
mListView = getListView();
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB)
{
mListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
mListView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
@Override
public boolean onCreateActionMode(android.view.ActionMode mode, android.view.Menu menu) {
// Inflate the menu for the CAB
menu.clear();
menu.add(1, 1, 2, "Delete").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
menu.add(1, 3, 1, "Save").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
return true;
}
@Override
public boolean onActionItemClicked(android.view.ActionMode mode, android.view.MenuItem item) {
mActionMode = mode;
if (item.getGroupId() == 1)
{
switch(itemId)
{
case 0:
DeleteItem();
break;
case 1:
SaveItem();
break;
}
}
}
}
}
}
@Override
public boolean onContextItemSelected(final android.view.MenuItem item) {
if (item.getGroupId() == 1) {
final AdapterContextMenuInfo info = (AdapterContextMenuInfo)item.getMenuInfo();
final Integer position = info.position;
final int itemId = item.getItemId();
switch(itemId)
{
case 0:
DeleteItem();
break;
case 1:
SaveItem();
break;
}
}
return super.onContextItemSelected(item);
}
@Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu (menu);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.my_menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
}
ViewPager code
public class Main extends SherlockFragmentActivity
{
private static List<Integer> mIds;
@Override
public void onCreate(final Bundle icicle)
{
super.onCreate(null);
setContentView(R.layout.main);
mViewPager = (ViewPager)findViewById(R.id.viewpager); //view pager exists, so we are using the portait layout
if (mViewPager != null)
{
mIds = new ArrayList<Integer>();
mIds.add(0);
mIds.add(1);
mIds.add(2);
}
else //in landscape
{
ListFragment lf = (ListFragment)getSupportFragmentManager().findFragmentById(R.id.fragmentList);
if (lf == null)
lf = new ListFragment();
DetailFragment df = (DetailFragment)getSupportFragmentManager().findFragmentById(R.id.fragmentDetail);
if (df == null)
{
df = new DetailFragment();
df.setArguments(getIntent().getExtras());
}
getSupportFragmentManager().beginTransaction().add(R.id.fragmentList, lf).commit();
getSupportFragmentManager().beginTransaction().add(R.id.fragmentDetail, df).commit();
}
}
private static class MyFragmentPagerAdapter extends FragmentStatePagerAdapter {
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int index) {
//can't use getSupportFragmentManager().findFragmentById() here because I get a "Cannot make a static reference to the non-static method" error
if (index == 0)
return ListFragment.newInstance();
else
return DetailFragment.newInstance(mIds.get(index-1));
}
@Override
public int getCount() {
return 4;
}
}
}
This solution on this question fixed my issue:
How to handle onContextItemSelected in a multi fragment activity?
using getUserVisibleHint()
in onContextItemSelected
.