Otto イベント バスを使用して、Activity
との間で通信しFragment
ます。コントロールActivity
は独自Stack
のカスタム back イベントを維持します。各イベントには back action が含まれますRunnable
。つまり、back ボタンが押されたときに実行されるアクションです。
このアプローチの利点は、設計がわずかに分離されていることであり、より多くのフラグメントに合わせて拡張する必要があります。読みやすくするために、ここでは Otto イベントを my 内に定義しましたFragment
が、これらはプロジェクト内の別の場所に簡単に移動できます。
これがどのように行われるかを理解するためのサンプルコードです。
フラグメント
Fragmentは、Otto イベント バスにaをポストし、イベントがカスタム スタックからポップされたときに実行されるアクションを提供することによって、次のバック プレスを取得する意図を通知します。Fragment がデタッチされると、 バスに を送信して、アクティビティのカスタム スタックから の back アクションをすべて削除します。BackStackRequestEvent
Runnable
Activity
ClearBackStackEvent
Fragment
public class MyFragment extends Fragment {
private final String BACK_STACK_ID = "MY_FRAGMENT";
...
public class BackStackRequestEvent {
private Runnable action;
private String id;
public BackStackRequestEvent(Runnable action, String id) {
this.action = action;
this.id = id;
}
public void goBack() {
action.run();
}
public String getId() {
return id;
}
}
public class ClearBackStackEvent {
private String id;
public ClearBackStackEvent(String id) {
this.id = id;
}
public String getId() {
return id;
}
}
...
@Override
public void onDetach() {
super.onDetach();
// Get your Otto singleton and notify Activity that this
// Fragment's back actions are no longer needed
// The Fragment lifecycle stage in which you do this might vary
// based on your needs
EventBus.getInstance().post(new ClearBackStackEvent(BACK_STACK_ID));
}
...
public void someChangeInFragment() {
// Notify the Activity that we want to intercept the next onBackPressed
EventBus.getInstance().post(new BackStackRequestEvent(new Runnable()
{
@Override
public void run() {
// Reverse what we did
doBackAction();
}
}, BACK_STACK_ID)); // constant used later to remove items from Stack
}
}
アクティビティ
アクティビティは、上でおよびで定義したイベントへの関心を登録/登録解除します。new を受け取ると、それをカスタム バック スタックに追加します。が呼び出されると、バック スタックをポップし、フラグメントの. スタックに何もない場合は、通常のバック動作に従います。onStart()
onStop()
BackStackRequestEvent
onBackPressed()
BackStackRequestEvent.goBack()
Runnable
フラグメントがデタッチされると、アクティビティは を受け取り、提供された のすべてのアイテムをスタックからClearBackStackEvent
削除します。id
public class MyActivity extends Activity {
private Stack<MyFragment.BackStackRequestEvent> customBackStack = new Stack<>();
...
@Override
protected void onStart() {
super.onStart();
EventBus.getInstance().register(this);
}
@Override
protected void onStop() {
super.onStop();
EventBus.getInstance().unregister(this);
}
@Subscribe // Annotation indicating that we want to intercept this Otto event
public void backStackRequested(MyFragment.BackStackRequestEvent request) {
customBackStack.push(request);
}
@Override
public void onBackPressed() {
if (customBackStack.empty()) {
// No custom actions so default behaviour followed
super.onBackPressed();
}
else {
// Pop the custom action and call its goBack() action
MyFragment.BackStackRequestEvent back = customBackStack.pop();
back.goBack();
}
}
@Subscribe
public void clearBackStackRequested(MyFragment.ClearBackStackEvent request) {
String id = request.getId();
for (MyFragment.BackStackRequestEvent backItem : customBackStack) {
if (backItem.getId().contentEquals(id)) {
customBackStack.remove(backItem);
}
}
}
}