mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-02-09 22:51:57 +08:00
Android native stack bugfixes. (#190)
A few bugs fixed with android native stack in this commit: - fixed a problem with views not resizing when keyboard appears, the bug was due to onMeasure forwardin getHeight which was the old height of the container instead of the changed one - fixed a problem with back button behavior not being consistent. Now back button is controlled by 'gestureEnabled' to emulate iOS behavior where there is no hw back button but you can swipe back instead. - added compatibility for "contained" modal styles - for now we always render "containted" fragments on Android, plan to add a way to render in dialogs in the future
This commit is contained in:
committed by
GitHub
parent
4749405d64
commit
d4636d3130
@@ -1,7 +1,6 @@
|
||||
package com.swmansion.rnscreens;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.TypedValue;
|
||||
@@ -29,17 +28,26 @@ public class ScreenStackHeaderConfig extends ViewGroup {
|
||||
private int mTitleFontSize;
|
||||
private int mBackgroundColor;
|
||||
private boolean mIsHidden;
|
||||
private boolean mGestureEnabled = true;
|
||||
private boolean mIsBackButtonHidden;
|
||||
private boolean mIsShadowHidden;
|
||||
private int mTintColor;
|
||||
private final Toolbar mToolbar;
|
||||
|
||||
private boolean mIsAttachedToWindow = false;
|
||||
|
||||
private OnBackPressedCallback mBackCallback = new OnBackPressedCallback(false) {
|
||||
@Override
|
||||
public void handleOnBackPressed() {
|
||||
getScreenStack().dismiss(getScreenFragment());
|
||||
ScreenStack stack = getScreenStack();
|
||||
Screen current = getScreen();
|
||||
if (stack.getTopScreen() == current) {
|
||||
stack.dismiss(getScreenFragment());
|
||||
}
|
||||
mBackCallback.remove();
|
||||
}
|
||||
};
|
||||
|
||||
private OnClickListener mBackClickListener = new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
@@ -68,7 +76,14 @@ public class ScreenStackHeaderConfig extends ViewGroup {
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
update();
|
||||
mIsAttachedToWindow = true;
|
||||
onUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
mIsAttachedToWindow = false;
|
||||
}
|
||||
|
||||
private Screen getScreen() {
|
||||
@@ -101,14 +116,27 @@ public class ScreenStackHeaderConfig extends ViewGroup {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void installBackCallback() {
|
||||
mBackCallback.remove();
|
||||
Fragment fragment = getScreenFragment();
|
||||
fragment.requireActivity().getOnBackPressedDispatcher().addCallback(fragment, mBackCallback);
|
||||
}
|
||||
|
||||
private void update() {
|
||||
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;
|
||||
|
||||
// we need to clean up back handler especially in the case given screen is no longer on top
|
||||
// because we don't want it to capture back event if it is not responsible for handling it
|
||||
// as that would block other handlers from running
|
||||
mBackCallback.remove();
|
||||
|
||||
if (!mIsAttachedToWindow || !isTop) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isRoot && isTop && mGestureEnabled) {
|
||||
Fragment fragment = getScreenFragment();
|
||||
fragment.requireActivity().getOnBackPressedDispatcher().addCallback(fragment, mBackCallback);
|
||||
mBackCallback.setEnabled(true);
|
||||
}
|
||||
|
||||
if (mIsHidden) {
|
||||
if (mToolbar.getParent() != null) {
|
||||
getScreenFragment().removeToolbar();
|
||||
@@ -125,13 +153,7 @@ public class ScreenStackHeaderConfig extends ViewGroup {
|
||||
ActionBar actionBar = activity.getSupportActionBar();
|
||||
|
||||
// hide back button
|
||||
final ScreenStack stack = getScreenStack();
|
||||
boolean isRoot = stack == null ? true : stack.getRootScreen() == parent;
|
||||
actionBar.setDisplayHomeAsUpEnabled(isRoot ? false : !mIsBackButtonHidden);
|
||||
if (!isRoot) {
|
||||
installBackCallback();
|
||||
}
|
||||
mBackCallback.setEnabled(!isRoot);
|
||||
|
||||
// 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
|
||||
@@ -268,6 +290,10 @@ public class ScreenStackHeaderConfig extends ViewGroup {
|
||||
mIsShadowHidden = hideShadow;
|
||||
}
|
||||
|
||||
public void setGestureEnabled(boolean gestureEnabled) {
|
||||
mGestureEnabled = gestureEnabled;
|
||||
}
|
||||
|
||||
public void setHideBackButton(boolean hideBackButton) {
|
||||
mIsBackButtonHidden = hideBackButton;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user