【发布时间】:2017-07-05 00:09:08
【问题描述】:
通过调用getActivity().startActionMode(calback); 启动的动作模式在按下返回按钮后会自动取消。有可能避免这种行为吗?在动作模式下的某些情况下按下返回按钮后,我需要执行另一个操作。
【问题讨论】:
通过调用getActivity().startActionMode(calback); 启动的动作模式在按下返回按钮后会自动取消。有可能避免这种行为吗?在动作模式下的某些情况下按下返回按钮后,我需要执行另一个操作。
【问题讨论】:
这是一个有趣的问题。当 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来解决。
【讨论】:
dispatchKeyEvent()。如果你使用它,它就会被调用(ActionBarSherlock 使用 ActionBar for Android 3.x 的自定义实现)。
建议的解决方案对我不起作用。所以我决定手动创建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 {...}
【讨论】: