通过调用启动的动作模式getActivity().startActionMode(calback);
在按下返回按钮后自动取消。有可能避免这种行为吗?在动作模式下的某些情况下按下后退按钮后,我需要执行另一项操作。
3 回答
这是一个有趣的问题。当 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 来解决。
建议的解决方案对我不起作用。所以我决定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();
...
}
};
创建您自己的 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 {...}