Подтвердить что ты не робот

Предотвратите отмену действия, нажав кнопку "Назад"

Действие, начатое вызовом getActivity().startActionMode(calback);, автоматически отменяется после нажатия кнопки "Назад". Возможно ли избежать такого поведения? Мне нужно сделать еще одну операцию после нажатия кнопки в какой-либо ситуации во время действия.

4b9b3361

Ответ 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 для его решения.

Ответ 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 {...}