17

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

4

3 回答 3

32

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

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

@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 来解决。

于 2012-09-02T13:02:21.200 回答
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();
            ...
        }
    };
于 2016-02-14T04:25:42.907 回答
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 {...}

于 2017-07-04T16:09:08.227 回答