From 22d4400b93955fb361e5362837d5446f5aac1880 Mon Sep 17 00:00:00 2001 From: Krzysztof Magiera Date: Tue, 4 Feb 2020 22:20:41 +0100 Subject: [PATCH] =?UTF-8?q?Render=20Android=20back=20button=20for=20root?= =?UTF-8?q?=20screens=20of=20nested=20stack=20navi=E2=80=A6=20(#306)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change allows for root screens of nested stack navigators on Android to display back button in the navigation bar. Navigating back is still possible using hw back because of the way hw back is handled by nested fragment containers. However, despite hw back functioning properly, before this change we would not allow for the soft back button to be rendered in the header. This change adds this possibility to keep software back consistent with the hw back button functionality. This behavior can still be disabled/adjusted using hideBackButton property of the header config component. --- .../rnscreens/ScreenStackFragment.java | 9 +++++++++ .../rnscreens/ScreenStackHeaderConfig.java | 17 ++++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.java b/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.java index aa2785d9..4a2afb59 100644 --- a/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.java +++ b/android/src/main/java/com/swmansion/rnscreens/ScreenStackFragment.java @@ -99,4 +99,13 @@ public class ScreenStackFragment extends ScreenFragment { public boolean isDismissable() { return mScreenView.isGestureEnabled(); } + + public void dismiss() { + ScreenContainer container = mScreenView.getContainer(); + if (container instanceof ScreenStack) { + ((ScreenStack) container).dismiss(this); + } else { + throw new IllegalStateException("ScreenStackFragment added into a non-stack container"); + } + } } diff --git a/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.java b/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.java index 18e1d4d0..aa1819a6 100644 --- a/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.java +++ b/android/src/main/java/com/swmansion/rnscreens/ScreenStackHeaderConfig.java @@ -41,7 +41,16 @@ public class ScreenStackHeaderConfig extends ViewGroup { private OnClickListener mBackClickListener = new OnClickListener() { @Override public void onClick(View view) { - getScreenStack().dismiss(getScreenFragment()); + ScreenStack stack = getScreenStack(); + ScreenStackFragment fragment = getScreenFragment(); + if (stack.getRootScreen() == fragment.getScreen()) { + Fragment parentFragment = fragment.getParentFragment(); + if (parentFragment instanceof ScreenStackFragment) { + ((ScreenStackFragment) parentFragment).dismiss(); + } + } else { + fragment.dismiss(); + } } }; @@ -117,7 +126,6 @@ public class ScreenStackHeaderConfig extends ViewGroup { public void onUpdate() { Screen parent = (Screen) getParent(); final ScreenStack stack = getScreenStack(); - boolean isRoot = stack == null ? true : stack.getRootScreen() == parent; boolean isTop = stack == null ? true : stack.getTopScreen() == parent; if (!mIsAttachedToWindow || !isTop || mDestroyed) { @@ -131,6 +139,9 @@ 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); } @@ -140,7 +151,7 @@ public class ScreenStackHeaderConfig extends ViewGroup { ActionBar actionBar = activity.getSupportActionBar(); // hide back button - actionBar.setDisplayHomeAsUpEnabled(isRoot ? false : !mIsBackButtonHidden); + actionBar.setDisplayHomeAsUpEnabled((isRoot && !isNested) ? false : !mIsBackButtonHidden); // 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