防止通过按返回按钮取消操作模式

17

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

可以通过重写ActionMode.Callback接口中的onDestroyActionMode(ActionMode mode)方法来实现在按下后退按钮后执行其他操作的需求。在此方法中,您可以处理后续的操作并防止系统默认地取消操作模式。
3个回答

32

这是一个有趣的问题。当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来解决这个问题。

你能否更清楚地解释一下“使用ActionBarSherlock的ActionMode来解决它”是什么意思? - rfgamaral
3
在Android 3.1设备上,如果你不使用ActionBarSherlock,dispatchKeyEvent()将不会被调用。如果你使用它,它将会被调用(ActionBarSherlock在Android 3.x中使用自定义实现的ActionBar)。 - Tomik
2
这个答案对我没用。有关我的问题,你有什么想法?http://stackoverflow.com/questions/32683145/prevent-back-button-whilst-actionmode-is-active - Kuffs

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();
            ...
        }
    };

0

创建您自己的 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 {...}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接