通过调用getActivity().startActionMode(callback);
开始的操作模式将在按下后退按钮后自动取消。有可能避免这种行为吗?在某些情况下,我需要在后退按钮被按下后执行另一个操作。
ActionMode.Callback
接口中的onDestroyActionMode(ActionMode mode)
方法来实现在按下后退按钮后执行其他操作的需求。在此方法中,您可以处理后续的操作并防止系统默认地取消操作模式。通过调用getActivity().startActionMode(callback);
开始的操作模式将在按下后退按钮后自动取消。有可能避免这种行为吗?在某些情况下,我需要在后退按钮被按下后执行另一个操作。
ActionMode.Callback
接口中的onDestroyActionMode(ActionMode mode)
方法来实现在按下后退按钮后执行其他操作的需求。在此方法中,您可以处理后续的操作并防止系统默认地取消操作模式。这是一个有趣的问题。当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()
不会被调用,因此你可以放心地使用这段代码。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 {...}
dispatchKeyEvent()
将不会被调用。如果你使用它,它将会被调用(ActionBarSherlock在Android 3.x中使用自定义实现的ActionBar)。 - Tomik