Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.common.MapBuilder;

import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.Stack;

Expand All @@ -36,6 +38,7 @@ public class ScreenCoordinator {
private static final String TAG = ScreenCoordinator.class.getSimpleName();
static final String EXTRA_PAYLOAD = "payload";
private static final String TRANSITION_GROUP = "transitionGroup";
private static final String STACK_PREFIX = "STACK";

enum PresentAnimation {
Modal(R.anim.slide_up, R.anim.delay, R.anim.delay, R.anim.slide_down),
Expand Down Expand Up @@ -74,7 +77,38 @@ public ScreenCoordinator(AppCompatActivity activity, ScreenCoordinatorLayout con
this.activity = activity;
this.container = container;
container.setFragmentManager(activity.getSupportFragmentManager());
// TODO: restore state
restoreStack();
}

/**
* If there are Fragments in the Activity stack, restore them into our backStacks. We know the
* order in which to restore the Fragments by tagging them with the total size of our backStacks
* at the time they were added.
*
* This is useful when the app goes to background on a device with "Don't keep activities"
* turned on or when the Activity is otherwise killed.
*/
private void restoreStack() {
boolean hasFragments = true;
int stackPosition = 0;

while (hasFragments) {
String fragmentTag = String.valueOf(stackPosition);
Fragment pushedFragment = activity.getSupportFragmentManager().findFragmentByTag(fragmentTag);
Fragment presentedFragment = activity.getSupportFragmentManager().findFragmentByTag(STACK_PREFIX + fragmentTag);

if (presentedFragment != null) {
BackStack backStack = new BackStack(getNextStackTag(), PresentAnimation.Modal, null);
backStacks.push(backStack);
getCurrentBackStack().pushFragment(presentedFragment);
} else if (pushedFragment != null) {
getCurrentBackStack().pushFragment(pushedFragment);
} else {
hasFragments = false;
}

stackPosition++;
}
}

void onSaveInstanceState(Bundle outState) {
Expand Down Expand Up @@ -111,7 +145,7 @@ public void pushScreen(Fragment fragment, @Nullable Bundle options) {
BackStack bsi = getCurrentBackStack();
ft
.detach(currentFragment)
.add(container.getId(), fragment)
.add(container.getId(), fragment, String.valueOf(getTotalBackStackSize()))
.addToBackStack(null)
.commit();
bsi.pushFragment(fragment);
Expand Down Expand Up @@ -187,8 +221,11 @@ public void presentScreen(Fragment fragment, PresentAnimation anim, @Nullable Pr
container.willDetachCurrentScreen();
ft.detach(currentFragment);
}

// Use STACK_PREFIX here because each `presentScreen` creates a new BackStack. We need to
// know when that's the case when restoring the fragments.
ft
.add(container.getId(), fragment)
.add(container.getId(), fragment, STACK_PREFIX + String.valueOf(getTotalBackStackSize()))
.addToBackStack(bsi.getTag())
.commit();
activity.getSupportFragmentManager().executePendingTransactions();
Expand Down Expand Up @@ -284,6 +321,18 @@ private BackStack getCurrentBackStack() {
return backStacks.peek();
}

private int getTotalBackStackSize() {
int totalSize = 0;
if (backStacks.size() > 0) {

List<BackStack> stackList = new ArrayList<BackStack>(backStacks);
for (BackStack bsi : stackList) {
totalSize += bsi.getSize();
}
}
return totalSize;
}

@NonNull
private FrameLayout createContainerView() {
return new FrameLayout(activity);
Expand Down