通过按后退按钮禁止取消操作模式

时间:2012-07-30 16:35:01

标签: android android-actionbar

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

3 个答案:

答案 0 :(得分:31)

这是一个有趣的问题。当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。我发现的唯一问题是在使用原生ActionMode时在Android 3.1设备上,在这种情况下不会调用dispatchKeyEvent()。使用ActionBarSherlock的ActionMode来解决它。

答案 1 :(得分:0)

建议的解决方案对我不起作用。所以我决定手动创建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();
            ...
        }
    };

答案 2 :(得分:0)

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

@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 {...}