9

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

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

在此处输入图像描述

在此处输入图像描述

在第二张图片中,您可以看到操作模式栏仍然存在。所以我的问题是:如果我离开片段,我应该在哪个方法中调用我的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();
      }
  }
}
4

5 回答 5

7

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

您最好的选择是使用ViewPager.OnPageChangeListener, 并在其中显示和隐藏 ActionMode onPageSelected(..)(即,如果所选页面不是具有 ActionMode 的页面,则隐藏 ActionMode)。您可能必须在托管 ViewPager 的 Activity 中实现这一点。

于 2013-08-13T09:43:52.017 回答
7

这对我有用——

  1. 在 MyFragment 中保持对动作模式的静态引用:

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. ViewPager.OnPageChangeListener在 MyViewPagerActivity 中设置。

 mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {

            ....

            @Override
            public void onPageScrollStateChanged(int state) {
                if(MyFragment.mActionMode != null) MyFragment.mActionMode.finish();
            }


        });

于 2015-12-23T03:21:46.527 回答
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);
    }
}
于 2014-10-03T15:40:45.627 回答
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();
    }
}
于 2015-10-07T14:18:52.437 回答
2

You can use the onDestroyOptionsMenu() method inside your Fragment:

public void onDestroyOptionsMenu() {
    super.onDestroyOptionsMenu();
    if (mActionMode != null) {
        mActionMode.finish();
        mActionMode = null;
    }
}
于 2017-08-28T10:30:14.643 回答