3

我的应用程序有一个ListView,我使用Contextual Action Bar用于SDK 11以上的设备,以及旧设备的旧弹出上下文操作。我知道有一种方法可以在较旧的设备上使用CAB,但我试图实施它,并发现不值得为最终将被淘汰的设备付出努力。我知道这是一些代码重复,但理论上,我将摆脱旧的弹出式行为(强调“理论上”)。onContextItemSelected调用了两次片段

无论如何,当我使用模拟器时,CAB可以正常工作,但旧设备的旧弹出操作在该事件中放置断点时似乎会弹出onContextItemSelected两次。我刚刚开始为我的应用实施ViewPager,并且在ViewPager之前没有发生这种情况,所以不确定是否会导致问题。

这是我使用的代码:

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代码

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; 
     } 
    } 
} 
+0

*似乎命中*?如果您选择*删除* * DeleteItem()*方法被调用两次? – Luksprog

+0

@Luksprog是的,实际上在'DeleteItem()'我使用'AlertDialog'来确认删除动作,两个对话框显示一个在另一个之上。在'DeleteItem()'中放置一个断点,它会被点击两次。 –

+0

你可以发布ViewPager的代码(它的适配器,我猜你使用的是与以前的问题相同的片段列表)?正如你所说的在ViewPager之前一切正常,它必须与该ViewPager有关。 – Luksprog

回答

3

对这个问题该解决方案固定我的问题:

How to handle onContextItemSelected in a multi fragment activity?

使用getUserVisibleHint()onContextItemSelected

+0

getUserVisibleHint()不可靠,当你有多个相同类的片段时。在这种情况下,您可以使用下一个答案:http://stackoverflow.com/a/41595222/1223728 – Borzh

相关问题