【问题标题】:Prevent to cancel Action Mode by press back button防止按返回按钮取消操作模式
【发布时间】:2017-07-05 00:09:08
【问题描述】:

通过调用getActivity().startActionMode(calback); 启动的动作模式在按下返回按钮后会自动取消。有可能避免这种行为吗?在动作模式下的某些情况下按下返回按钮后,我需要执行另一个操作。

【问题讨论】:

    标签: android android-actionbar


    【解决方案1】:

    这是一个有趣的问题。当 ActionMode 处于活动状态时,后退键事件在内部被消耗。该事件传播到onBackPressed()onKeyUp(int keyCode, KeyEvent event) 回调。

    幸运的是,您可以使用仍然被调用的dispatchKeyEvent(KeyEvent event)

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if(mActionModeIsActive) {
            if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
               // handle your back button code here
               return true; // consumes the back key event - ActionMode is not finished
            }
        }
        return super.dispatchKeyEvent(event);
    }
    

    您可能想知道如果您在 ActionMode 中有一个子菜单并使用返回键将其关闭,会出现什么情况。在这种情况下,dispatchKeyEvent() 不会被调用,因此您可以安全地使用代码。

    上面的代码也适用于 ActionBarSherlock。我发现的唯一问题是在 Android 3.1 设备上使用本机 ActionMode 时,在这种情况下不会调用 dispatchKeyEvent()。使用ActionBarSherlock的ActionMode来解决。

    【讨论】:

    • 您能否更清楚地了解“使用 ActionBarSherlock 的 ActionMode 来解决它”的意思?
    • 在 Android 3.1 设备上,如果您不使用 ActionBarSherlock,则不会调用 dispatchKeyEvent()。如果你使用它,它就会被调用(ActionBarSherlock 使用 ActionBar for Android 3.x 的自定义实现)。
    • 这个答案对我不起作用。对我的问题有什么想法吗?stackoverflow.com/questions/32683145/…
    【解决方案2】:

    建议的解决方案对我不起作用。所以我决定手动创建back 事件。我的片段中需要这个事件,所以我创建了BaseFragment,我的所有片段都将扩展。

    public abstract class BaseFragment extends Fragment {
    
        private ActionModeState actionModeState = ActionModeState.ITEM_NOT_CLICKED;
    
        protected enum ActionModeState {
            ITEM_NOT_CLICKED, ITEM_CLICKED
        }
    
        protected void onActionItemClicked() {
            actionModeState = ActionModeState.ITEM_CLICKED;
        }
    
        protected void onDestroyActionMode() {
            if (actionModeState == ActionModeState.ITEM_NOT_CLICKED) {
                onActionModeBackPressed();
            } else {
                // reset state
                actionModeState = ActionModeState.ITEM_NOT_CLICKED;
            }
        }
    
        protected void onActionModeBackPressed() { }
    
    }
    

    主要片段

    public class YourMainFragment extends BaseMapFragment {
    
        @Override
        public void onActionModeBackPressed() {
            // you code for action mode back button
        }
    
    
        private ActionMode.Callback actionModeCallback = new ActionMode.Callback() {
    
            @Override
            public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
                YourMainFragment.this.onActionItemClicked();
                ....
            }
    
            @Override
            public void onDestroyActionMode(ActionMode mode) {
                YourMainFragment.this.onDestroyActionMode();
                ...
            }
        };
    

    【讨论】:

      【解决方案3】:

      创建您自己的 Window.Callback 并在事件传递给 AppCompatDelegateImplBase 之前拦截它。

      @Override
          public boolean onCreateActionMode(ActionMode mode, Menu menu) {
              //default delegate
              final Window window = getActivity().getWindow();
              mWindowCallbackDelegate = new WindowCallbackDelegate(window.getCallback(), this);
              window.setCallback(mWindowCallbackDelegate);
              return true;
          }
      

      在你自己的委托中:

      @Override
      public boolean dispatchKeyEvent(KeyEvent event) {
          return myWindowDelegate.dispatchKeyEvent(event) || mOriginalWindowCallback.dispatchKeyEvent(event);
      }
      

      当你销毁动作模式时,恢复对前一个委托的引用

       @Override
              public void onDestroyActionMode(ActionMode mode) {
              Window.Callback originalWindowCallback = mWindowCallbackDelegate.getOriginalWindowCallback();
              if (originalWindowCallback != null) {
                  getActivity().getWindow().setCallback(originalWindowCallback);
              }}
      

      您拥有代表签名:

      public class WindowCallbackDelegate implements Window.Callback {...}

      【讨论】:

        猜你喜欢
        • 2023-04-02
        • 1970-01-01
        • 2012-05-17
        • 2012-04-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多