From 06b928f5c1a39e8e7b96bb360e4ac425a4c1638d Mon Sep 17 00:00:00 2001 From: Krzysztof Magiera Date: Wed, 5 Feb 2020 16:22:10 +0100 Subject: [PATCH] Fix showing sw back button on nested stack on Android. (#308) This change fixes a problem with native stack on Android where we'd display a sw back button on screens that are nested stack navigatodespite the fact those screens were the initial screens in the whole container stack. In #306 we introuced a change that would allow for displaying sw back in nested stacks, however that change did not handle the case where screen is a root screen of a container that is nested and placed as an initial screen in another container. --- .../rnscreens/ScreenStackFragment.java | 21 +++++++++++++++++++ .../rnscreens/ScreenStackHeaderConfig.java | 5 +---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.java b/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.java index 4a2afb59..fe9b6bfa 100644 --- a/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.java +++ b/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.java @@ -11,6 +11,7 @@ import android.widget.LinearLayout; import androidx.annotation.Nullable; import androidx.appcompat.widget.Toolbar; import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.fragment.app.Fragment; import com.facebook.react.uimanager.PixelUtil; import com.google.android.material.appbar.AppBarLayout; @@ -100,6 +101,26 @@ public class ScreenStackFragment extends ScreenFragment { return mScreenView.isGestureEnabled(); } + public boolean canNavigateBack() { + ScreenContainer container = mScreenView.getContainer(); + if (container instanceof ScreenStack) { + if (((ScreenStack) container).getRootScreen() == getScreen()) { + // this screen is the root of the container, if it is nested we can check parent container + // if it is also a root or not + Fragment parentFragment = getParentFragment(); + if (parentFragment instanceof ScreenStackFragment) { + return ((ScreenStackFragment) parentFragment).canNavigateBack(); + } else { + return false; + } + } else { + return true; + } + } else { + throw new IllegalStateException("ScreenStackFragment added into a non-stack container"); + } + } + public void dismiss() { ScreenContainer container = mScreenView.getContainer(); if (container instanceof ScreenStack) { diff --git a/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.java b/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.java index aa1819a6..d03ca296 100644 --- a/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.java +++ b/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.java @@ -139,9 +139,6 @@ public class ScreenStackHeaderConfig extends ViewGroup { return; } - boolean isRoot = stack == null ? true : stack.getRootScreen() == parent; - boolean isNested = (parent.getFragment().getParentFragment() instanceof ScreenStackFragment); - if (mToolbar.getParent() == null) { getScreenFragment().setToolbar(mToolbar); } @@ -151,7 +148,7 @@ public class ScreenStackHeaderConfig extends ViewGroup { ActionBar actionBar = activity.getSupportActionBar(); // hide back button - actionBar.setDisplayHomeAsUpEnabled((isRoot && !isNested) ? false : !mIsBackButtonHidden); + actionBar.setDisplayHomeAsUpEnabled(getScreenFragment().canNavigateBack() ? !mIsBackButtonHidden : false); // when setSupportActionBar is called a toolbar wrapper gets initialized that overwrites // navigation click listener. The default behavior set in the wrapper is to call into