呼び出しによって開始されたアクションモードはgetActivity().startActionMode(calback);
、戻るボタンを押すと自動的にキャンセルされます。この動作を回避することは可能ですか?アクションモード中にある状況で戻るボタンが押された後、別の操作を行う必要があります。
3 に答える
これは興味深い問題です。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でも機能します。私が見つけた唯一の問題は、ネイティブActionModeが使用されている場合のAndroid 3.1デバイスであり、この場合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();
...
}
};
AppCompatDelegateImplBaseに渡される前に、独自のWindow.Callbackおよびインターセプトイベントを作成します。
@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 {...}