片段中的上下文动作模式 - 如果没有聚焦则关闭?

时间:2013-08-13 08:39:19

标签: android android-viewpager android-contextmenu android-actionmode

我在嵌套的fragement中实现了一个上下文动作模式栏。此片段是视图分页器的一部分,视图分页器也是片段和导航抽屉的一部分。

我的问题:如果片段不再集中,我想关闭上下文操作模式栏。因此,如果我在视图寻呼机中滑动,则应关闭操作模式栏。但是如果我使用嵌套片段的onPause()方法,则不会直接调用该方法。通常它等到我向前滑了两三次......这是一些照片:

enter image description here

enter image description here

在第二张图片中,您可以看到操作模式栏仍然存在。所以我的问题是: 我应该在哪种方法中调用actionModeBar.finish()方法,如果我离开片段,直接关闭操作模式栏?

也许片段的代码可以帮助你:

public class EditorFragment extends Fragment {

  private static final String KEY_POSITION="position";
  ListView listView;
  private boolean isMultipleList = false;
  private ActionMode acMode;
  private int counterChecked = 0;

  private ActionMode.Callback modeCallBack = new ActionMode.Callback() {

    public boolean onPrepareActionMode(ActionMode mode, Menu menu){
           return false;
       }

      public void onDestroyActionMode(ActionMode mode) {
          listView.clearChoices();
            for (int i = 0; i < listView.getChildCount(); i++)
                listView.setItemChecked(i, false);
                listView.post(new Runnable() {
                    @Override
                    public void run() {
                        listView.setChoiceMode(ListView.CHOICE_MODE_NONE);
                    }
                });
          isMultipleList = false;
          counterChecked = 0;
          mode = null;
       }

       public boolean onCreateActionMode(ActionMode mode, Menu menu) {
           mode.setTitle("1 Aufgabe");
           mode.getMenuInflater().inflate(R.menu.actionmode, menu);
           return true;
       }

       public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
           switch (item.getItemId()) {
           case R.id.actionmode_delete:
               int choiceCount = listView.getCount();
               SparseBooleanArray spBoolArray = listView.getCheckedItemPositions();

               DBAufgaben db = new DBAufgaben(MainActivity.getMContext());
               db.open();

               for (int i = 0; i < choiceCount; i++) {
                   if(spBoolArray.get(i)){
                       db.deletContact(listView.getItemIdAtPosition(i));
                   }

               }
                Cursor cursor = db.getAllRecords();
                AdapterEingang adapterE = new AdapterEingang(MainActivity.getMContext(), cursor, 0);
                listView.setAdapter(adapterE);
               db.close();
               mode.finish();
               break;
           case R.id.actionmode_cancel:
               mode.finish();
               break;
           }
           return false;
       }
    };

  //......//

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

      View rootView = null;
      int position = getArguments().getInt(KEY_POSITION, -1);

      switch(position){
      case 0:
          rootView = inflater.inflate(R.layout.pager_list, null);
          listView = (ListView) rootView.findViewById(R.id.pager_list);

          Context context = MainActivity.getMContext();

          DBAufgaben db = new DBAufgaben(context);

          db.open();
          Cursor cursor = db.getAllRecords();
          AdapterEingang adapterE = new AdapterEingang(context, cursor, 0);
          listView.setAdapter(adapterE);
          db.close();

          listView.setOnItemLongClickListener(new OnItemLongClickListener(){



                @Override
                public boolean onItemLongClick(AdapterView<?> adapterView, View view,
                        int position, long id) {
                    if(!isMultipleList){
                        acMode = MainActivity.getInstance().startActionMode(modeCallBack);
                        listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
                        listView.setItemChecked(position, true);
                        isMultipleList = true;
                        counterChecked++;
                        setNewTitle();                      
                    } else {
                        listView.setItemChecked(position, true);
                        counterChecked++;
                        setNewTitle();
                    }

                    return true;
                }

              });
          listView.setOnItemClickListener(new OnItemClickListener(){

            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position,
                    long id) {
                Log.d(getTag(), "Datensatz: "+String.valueOf(id));
                if(isMultipleList){
                    if(listView.isItemChecked(position)){
                        listView.setItemChecked(position, true);
                        counterChecked++;
                        setNewTitle();
                    } else {
                        listView.setItemChecked(position, false);
                        counterChecked--;
                        setNewTitle();
                    }

                }

            }

          });
          break;
      default:
          rootView = inflater.inflate(R.layout.frag_dummy, null);
          TextView txt = (TextView) rootView.findViewById(R.id.dummy_txt);
          txt.setText(String.valueOf(position));
          break;
      }



      return(rootView);
  }
  public void setNewTitle(){
      if(counterChecked == 1){
            acMode.setTitle(counterChecked+" Aufgabe");
        } else {
            acMode.setTitle(counterChecked+" Aufgaben");
        }
  }
  @Override
  public void onPause(){
      super.onPause();
      if(isMultipleList){
          acMode.finish();
      }
  }
}

5 个答案:

答案 0 :(得分:6)

ViewPagers在任何时候都保持多个页面处于活动状态(默认情况下,当前页面之前的页面和页面之后的页面),因此在您向外滑动两页之前不会调用onPause()。

您最好的选择是使用ViewPager.OnPageChangeListener,并在onPageSelected(..)中显示和隐藏ActionMode(即,如果所选页面不是具有ActionMode的页面,则隐藏ActionMode)。您可能必须在承载ViewPager的活动中实现此功能。

答案 1 :(得分:5)

这对我有用 -

  1. 在MyFragment中保留对动作模式的静态引用:
  2. public static ActionMode mActionMode;

        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            mActionMode = mode;
            return true;
        }
    
        @Override
        public void onDestroyActionMode(ActionMode mode) {
            mActionMode = null;
        }
    
    1. 在MyViewPagerActivity中设置ViewPager.OnPageChangeListener
    2.  mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
      
                  ....
      
                  @Override
                  public void onPageScrollStateChanged(int state) {
                      if(MyFragment.mActionMode != null) MyFragment.mActionMode.finish();
                  }
      
      
              });

答案 2 :(得分:4)

这对我有用:

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    if (!isVisibleToUser && this.listView != null) {
        //HACK this is done in order to finish the contextual action bar
        int choiceMode = this.listView.getChoiceMode();
        this.listView.setChoiceMode(choiceMode);
    }
}

答案 3 :(得分:3)

我将来自OP的代码与用户pomber建议的覆盖结合起来:

  • 创建操作模式时,我将ActionMode保存到类字段。
  • 当操作模式被销毁时,我将字段设置回null
  • 我在我的片段中覆盖setUserVisibleHint,如果在视图寻呼机中看不到该片段,则调用ActionMode#finish()
  • 如果用户在其他位置导航,我还会在片段的ActionMode#finish()方法中调用onPause()来关闭片段。

代码:

@Nullable
ActionMode mActionMode = null;

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    // Start out with a progress indicator.
    setListShownNoAnimation(false);

    setEmptyText(getText(R.string.no_forms_in_progress));

    getListView().setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE_MODAL);
    getListView().setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
        @Override
        public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
            // Here you can do something when items are selected/de-selected,
            // such as update the title in the CAB
        }

        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            MenuInflater inflater = mode.getMenuInflater();
            inflater.inflate(R.menu.context_saved_item, menu);
            inflater.inflate(R.menu.context_instance_list, menu);
            mActionMode = mode;
            return true;
        }

        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            return false;
        }

        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            switch (item.getItemId()) {
                case R.id.action_delete:
                    confirmDelete(getListView().getCheckedItemIds());
                    return true;
                case R.id.action_print:
                    print(getListView().getCheckedItemIds());
                    return true;
            }
            return false;
        }

        @Override
        public void onDestroyActionMode(ActionMode mode) {
            mActionMode = null;
        }
    });
}

@Override
public void onPause() {
    super.onPause();
    if (mActionMode != null) {
        mActionMode.finish();
    }
}

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (mActionMode != null && !isVisibleToUser) {
        mActionMode.finish();
    }
}

答案 4 :(得分:1)

您可以在片段中使用onDestroyOptionsMenu()方法:

public void onDestroyOptionsMenu() {
    super.onDestroyOptionsMenu();
    if (mActionMode != null) {
        mActionMode.finish();
        mActionMode = null;
    }
}