Prevent flicker in header when header is null on initial mount (when using default header sizes) (#4577)

* Prevent flicker in header in most common cases. Fixes https://github.com/react-navigation/react-navigation/issues/4264

* Update snapshots
This commit is contained in:
Brent Vatne 2018-06-26 13:27:43 -07:00 committed by GitHub
parent 369ac2b568
commit 54448ed070
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 48 additions and 7 deletions

View File

@ -156,6 +156,7 @@ exports[`Nested navigators renders succesfully as direct child 1`] = `
collapsable={undefined}
style={
Object {
"backgroundColor": "#F7F7F7",
"transform": Array [
Object {
"translateX": 0,
@ -265,6 +266,7 @@ exports[`Nested navigators renders succesfully as direct child 1`] = `
collapsable={undefined}
style={
Object {
"backgroundColor": "#F7F7F7",
"transform": Array [
Object {
"translateX": 0,

View File

@ -83,6 +83,7 @@ exports[`StackNavigator applies correct values when headerRight is present 1`] =
collapsable={undefined}
style={
Object {
"backgroundColor": "#F7F7F7",
"transform": Array [
Object {
"translateX": 0,
@ -288,6 +289,7 @@ exports[`StackNavigator renders successfully 1`] = `
collapsable={undefined}
style={
Object {
"backgroundColor": "#F7F7F7",
"transform": Array [
Object {
"translateX": 0,

View File

@ -491,7 +491,12 @@ class Header extends React.PureComponent {
const forceInset = headerForceInset || { top: 'always', bottom: 'never' };
return (
<Animated.View style={this.props.layoutInterpolator(this.props)}>
<Animated.View
style={[
this.props.layoutInterpolator(this.props),
{ backgroundColor: DEFAULT_BACKGROUND_COLOR },
]}
>
<SafeAreaView forceInset={forceInset} style={containerStyles}>
<View style={StyleSheet.absoluteFill}>
{options.headerBackground}
@ -529,9 +534,11 @@ if (Platform.OS === 'ios') {
};
}
const DEFAULT_BACKGROUND_COLOR = Platform.OS === 'ios' ? '#F7F7F7' : '#FFF';
const styles = StyleSheet.create({
container: {
backgroundColor: Platform.OS === 'ios' ? '#F7F7F7' : '#FFF',
backgroundColor: DEFAULT_BACKGROUND_COLOR,
...platformContainerStyles,
},
transparentContainer: {

View File

@ -58,7 +58,15 @@ function forLayout(props) {
const { first, last } = interpolate;
const index = scene.index;
const width = layout.initWidth;
// We really shouldn't render the scene at all until we know the width of the
// stack. That said, in every case that I have ever seen, this has just been
// the full width of the window. This won't continue to be true if we support
// layouts like iPad master-detail. For now, in order to solve
// https://github.com/react-navigation/react-navigation/issues/4264, I have
// opted for the heuristic that we will use the window width until we have
// measured (and they will usually be the same).
const width = layout.initWidth || Dimensions.get('window').width;
// Make sure the header stays hidden when transitioning between 2 screens
// with no header.

View File

@ -68,6 +68,20 @@ const animatedSubscribeValue = animatedValue => {
}
};
const getDefaultHeaderHeight = isLandscape => {
if (Platform.OS === 'ios') {
if (isLandscape && !Platform.isPad) {
return 32;
} else if (IS_IPHONE_X) {
return 88;
} else {
return 64;
}
} else {
return 56;
}
};
class StackViewLayout extends React.Component {
/**
* Used to identify the starting point of the position when the gesture starts, such that it can
@ -89,10 +103,18 @@ class StackViewLayout extends React.Component {
*/
_immediateIndex = null;
state = {
// Used when card's header is null and mode is float to make switch animation work correctly
floatingHeaderHeight: 0,
};
constructor(props) {
super(props);
this.state = {
// Used when card's header is null and mode is float to make transition
// between screens with headers and those without headers smooth.
// This is not a great heuristic here. We don't know synchronously
// on mount what the header height is so we have just used the most
// common cases here.
floatingHeaderHeight: getDefaultHeaderHeight(props.isLandscape),
};
}
_renderHeader(scene, headerMode) {
const { options } = scene.descriptor;