我使用Otto event bus 在我的Activity 和Fragments 之间进行通信。控制Activity 维护自己的自定义返回事件Stack,每个事件都包含一个返回动作Runnable,即按下返回按钮时应该采取什么动作。
这种方法的优点是设计更加解耦,并且可以扩展更多片段。为了便于阅读,我在我的Fragment 中定义了 Otto 事件,在这里,但是这些可以很容易地移动到您项目的其他地方。
这里有一些示例代码,让您了解它是如何完成的。
片段
片段通过 posting 和 BackStackRequestEvent 向 Otto 事件总线发出信号,它打算抓住下一次后按,并提供一个 Runnable 动作,以便在事件从 Activity 弹出时执行。 s 自定义堆栈。当 Fragment 分离时,它会向总线发送 ClearBackStackEvent 以从 Activity 的自定义堆栈中删除 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
}
}
活动
活动registers / unregisters 对我们上面在onStart() 和onStop() 中定义的事件感兴趣。当它收到一个新的BackStackRequestEvent 时,它会将它添加到它的自定义后台堆栈中。一旦调用了onBackPressed(),它就会弹出返回堆栈并使用BackStackRequestEvent.goBack() 调用返回操作,而BackStackRequestEvent.goBack() 又运行Fragment 的Runnable。如果堆栈上没有任何内容,则遵循正常的返回行为。
当 Fragment 被分离时,Activity 会收到一个 ClearBackStackEvent 并从 Stack 中删除提供的 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);
}
}
}
}