mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-02-13 09:39:18 +08:00
Improve StatusBar/Header Behavior (#2669)
* Track orientation change * Add tests for withOrientation * Better variable naming
This commit is contained in:
@@ -83,7 +83,7 @@
|
||||
"react": "16.0.0-alpha.12",
|
||||
"react-native": "^0.48.4",
|
||||
"react-native-vector-icons": "^4.2.0",
|
||||
"react-test-renderer": "^15.6.1"
|
||||
"react-test-renderer": "^16.0.0"
|
||||
},
|
||||
"jest": {
|
||||
"notify": true,
|
||||
|
||||
@@ -262,6 +262,7 @@ export type HeaderProps = {
|
||||
NavigationStackScreenOptions
|
||||
>,
|
||||
style: ViewStyleProp,
|
||||
isLandscape?: boolean,
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,6 +9,7 @@ import { Animated, Platform, StyleSheet, View } from 'react-native';
|
||||
import HeaderTitle from './HeaderTitle';
|
||||
import HeaderBackButton from './HeaderBackButton';
|
||||
import HeaderStyleInterpolator from './HeaderStyleInterpolator';
|
||||
import withOrientation from '../withOrientation';
|
||||
|
||||
import type {
|
||||
NavigationScene,
|
||||
@@ -281,14 +282,25 @@ class Header extends React.PureComponent<void, HeaderProps, HeaderState> {
|
||||
screenProps,
|
||||
progress,
|
||||
style,
|
||||
isLandscape,
|
||||
...rest
|
||||
} = this.props;
|
||||
|
||||
const { options } = this.props.getScreenDetails(scene);
|
||||
const headerStyle = options.headerStyle;
|
||||
const landscapeAwareStatusBarHeight = isLandscape ? 0 : STATUSBAR_HEIGHT;
|
||||
const containerStyles = [
|
||||
styles.container,
|
||||
{
|
||||
paddingTop: landscapeAwareStatusBarHeight,
|
||||
height: APPBAR_HEIGHT + landscapeAwareStatusBarHeight,
|
||||
},
|
||||
headerStyle,
|
||||
style,
|
||||
];
|
||||
|
||||
return (
|
||||
<Animated.View {...rest} style={[styles.container, headerStyle, style]}>
|
||||
<Animated.View {...rest} style={containerStyles}>
|
||||
<View style={styles.appBar}>{appBar}</View>
|
||||
</Animated.View>
|
||||
);
|
||||
@@ -315,9 +327,7 @@ if (Platform.OS === 'ios') {
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
paddingTop: STATUSBAR_HEIGHT,
|
||||
backgroundColor: Platform.OS === 'ios' ? '#F7F7F7' : '#FFF',
|
||||
height: STATUSBAR_HEIGHT + APPBAR_HEIGHT,
|
||||
...platformContainerStyles,
|
||||
},
|
||||
appBar: {
|
||||
@@ -353,4 +363,4 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
});
|
||||
|
||||
export default Header;
|
||||
export default withOrientation(Header);
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`it adds isLandscape to props 1`] = `
|
||||
<View
|
||||
isLandscape={false}
|
||||
/>
|
||||
`;
|
||||
15
packages/react-navigation/src/views/__tests__/withOrientation-test.js
vendored
Normal file
15
packages/react-navigation/src/views/__tests__/withOrientation-test.js
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import React from 'react';
|
||||
import { View } from 'react-native';
|
||||
import renderer from 'react-test-renderer';
|
||||
import withOrientation, { isOrientationLandscape } from '../withOrientation';
|
||||
|
||||
test('it adds isLandscape to props', () => {
|
||||
const WrappedComponent = withOrientation(View);
|
||||
const rendered = renderer.create(<WrappedComponent />).toJSON();
|
||||
expect(rendered).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('calculates orientation correctly', () => {
|
||||
const isLandscape = isOrientationLandscape({ width: 10, height: 1 });
|
||||
expect(isLandscape).toBeTruthy();
|
||||
});
|
||||
55
packages/react-navigation/src/views/withOrientation.js
vendored
Normal file
55
packages/react-navigation/src/views/withOrientation.js
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
// @flow
|
||||
|
||||
import React from 'react';
|
||||
import { Dimensions } from 'react-native';
|
||||
import hoistNonReactStatic from 'hoist-non-react-statics';
|
||||
|
||||
type WindowDimensions = {
|
||||
width: number,
|
||||
height: number,
|
||||
};
|
||||
|
||||
type InjectedProps = {
|
||||
isLandscape: boolean,
|
||||
};
|
||||
|
||||
type State = {
|
||||
isLandscape: boolean,
|
||||
};
|
||||
|
||||
export const isOrientationLandscape = ({
|
||||
width,
|
||||
height,
|
||||
}: WindowDimensions): boolean => width > height;
|
||||
|
||||
export default function<T: *>(WrappedComponent: ReactClass<T & InjectedProps>) {
|
||||
class withOrientation extends React.Component<void, T, State> {
|
||||
state: State;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
const isLandscape = isOrientationLandscape(Dimensions.get('window'));
|
||||
this.state = { isLandscape };
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
Dimensions.addEventListener('change', this.handleOrientationChange);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
Dimensions.removeEventListener('change', this.handleOrientationChange);
|
||||
}
|
||||
|
||||
handleOrientationChange = ({ window }: { window: WindowDimensions }) => {
|
||||
const isLandscape = isOrientationLandscape(window);
|
||||
this.setState({ isLandscape });
|
||||
};
|
||||
|
||||
render() {
|
||||
return <WrappedComponent {...this.props} {...this.state} />;
|
||||
}
|
||||
}
|
||||
|
||||
return hoistNonReactStatic(withOrientation, WrappedComponent);
|
||||
}
|
||||
@@ -2287,6 +2287,18 @@ fbjs@0.8.12:
|
||||
setimmediate "^1.0.5"
|
||||
ua-parser-js "^0.7.9"
|
||||
|
||||
fbjs@^0.8.16:
|
||||
version "0.8.16"
|
||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.16.tgz#5e67432f550dc41b572bf55847b8aca64e5337db"
|
||||
dependencies:
|
||||
core-js "^1.0.0"
|
||||
isomorphic-fetch "^2.1.1"
|
||||
loose-envify "^1.0.0"
|
||||
object-assign "^4.1.0"
|
||||
promise "^7.1.1"
|
||||
setimmediate "^1.0.5"
|
||||
ua-parser-js "^0.7.9"
|
||||
|
||||
fbjs@^0.8.9:
|
||||
version "0.8.15"
|
||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.15.tgz#4f0695fdfcc16c37c0b07facec8cb4c4091685b9"
|
||||
@@ -4587,12 +4599,12 @@ react-proxy@^1.1.7:
|
||||
lodash "^4.6.1"
|
||||
react-deep-force-update "^1.0.0"
|
||||
|
||||
react-test-renderer@^15.6.1:
|
||||
version "15.6.1"
|
||||
resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-15.6.1.tgz#026f4a5bb5552661fd2cc4bbcd0d4bc8a35ebf7e"
|
||||
react-test-renderer@^16.0.0:
|
||||
version "16.0.0"
|
||||
resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.0.0.tgz#9fe7b8308f2f71f29fc356d4102086f131c9cb15"
|
||||
dependencies:
|
||||
fbjs "^0.8.9"
|
||||
object-assign "^4.1.0"
|
||||
fbjs "^0.8.16"
|
||||
object-assign "^4.1.1"
|
||||
|
||||
react-timer-mixin@^0.13.2:
|
||||
version "0.13.3"
|
||||
|
||||
Reference in New Issue
Block a user