バックスタックの活用でバックキーで戻る等を実装する
想定事例
こんなActivityがあったとします。
途中のPopUpのパネルと上部に表示されている、画像を最大化させたImageViewと背景をグレーの半透明で敷いているViewはフラグメントをAddして実装しています。
DialogFragmentをフルカスタマイズして使えばいい事例ですが、
なにかの都合や普通のカスタムフラグメントを使用してActivity上にフロートしているUIを作ったり、閉じるのではなく開いたり閉じたりするようなフラグメントを作る場合もあると思います。
そんな場合にバックスタック活用で状態を管理するやり方。
仕様
フロートしてくる二つのFragmentはバックキーで自分を閉じる。
ActivityはFragmentが表示されていない場合にバックキーを押した場合かつtabが1番でないときは1番のタブに戻る。
Activityの実装
onBackPressedをオーバーライド
@Override
public void onBackPressed() {
//バックスタックの登録数をチェックして0であればPopUpは存在しない
if (0 == mFragmentManager.getBackStackEntryCount())『
if(mTabClickNo != 0){
//1番のタブに戻すような処理をここで実装するここではchangeTabというメソッドがあるという想定
changeTab(1);
return;
}
}
super.onBackPressed();
}
PopUpFragmentをバックスタックに登録
FragmentTransactionでAdd等する際にaddToBackStackする。
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.setCustomAnimations(R.anim.abc_fade_in, R.anim.abc_fade_out);
//mPopUpFragmentにフラグメントのインスタンスを格納しているとする
fragmentTransaction.add(R.id.root_layout, mPopUpFragment);
//addToBackStackしておくこれでBackStackに登録される
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
Fragment側の処理
PopupFragmentも画像拡大表示Fragmentも同じです。
事例でいくとPopupFragment側は画像拡大表示FragmentをImageViewタップ時に呼び出す処理があると思いますので、その際も先ほどのaddToBackStackをお忘れなく。
OnKeyListenerの設定
ここではOnCreateViewでLayouXMLをinflateしたあとView全体に匿名関数をセットしています。
またDialogFragmentではない想定なので、ClickEventを取得して下のActivityのオブジェクトがクリックされないようにします。
View rootView = inflater.inflate(R.layout.fragment_popup, container, false);
rootView.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
if (event.getAction() == KeyEvent.ACTION_UP) {
getFragmentManager().popBackStack();
return true;
} else {
return true;
}
}
return false;
}
});
rootView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
return;
}
});
以上の流れでバックキーを使ってFragmentの戻る動作をそこそこ楽に実装できます。