mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-04-29 04:45:19 +08:00
Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ee40dd7d24 | ||
|
|
18a48105c2 | ||
|
|
fbac47b696 | ||
|
|
9aab47dac2 | ||
|
|
67309c00a6 | ||
|
|
86a724cfe3 | ||
|
|
eb78128439 | ||
|
|
c39ec7a10c | ||
|
|
0ff3347e97 | ||
|
|
b9d55a6330 | ||
|
|
315e43701b | ||
|
|
1d573bc246 | ||
|
|
3bfb0b90d0 | ||
|
|
8a129afe13 | ||
|
|
ab2a63fe92 | ||
|
|
c411210ecc | ||
|
|
01e7296520 | ||
|
|
8f3e0997c5 | ||
|
|
3f3ef6485c | ||
|
|
b12abb553f | ||
|
|
e02841a979 | ||
|
|
e147f34555 | ||
|
|
81e0ce136e | ||
|
|
8ba727c2cf | ||
|
|
9a86ef8362 | ||
|
|
4fe7c92847 | ||
|
|
afecaaed7f |
@@ -119,6 +119,9 @@ const StacksInTabs = TabNavigator(
|
|||||||
tabBarPosition: 'bottom',
|
tabBarPosition: 'bottom',
|
||||||
animationEnabled: false,
|
animationEnabled: false,
|
||||||
swipeEnabled: false,
|
swipeEnabled: false,
|
||||||
|
tabBarOptions: {
|
||||||
|
showLabel: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
"react": "16.2.0",
|
"react": "16.2.0",
|
||||||
"react-native": "^0.52.0",
|
"react-native": "^0.52.0",
|
||||||
"react-navigation": "link:../..",
|
"react-navigation": "link:../..",
|
||||||
"react-navigation-redux-helpers": "^1.0.0",
|
"react-navigation-redux-helpers": "^1.0.3",
|
||||||
"react-redux": "^5.0.6",
|
"react-redux": "^5.0.6",
|
||||||
"redux": "^3.7.2"
|
"redux": "^3.7.2"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import React from 'react';
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { addNavigationHelpers, StackNavigator } from 'react-navigation';
|
import { addNavigationHelpers, StackNavigator } from 'react-navigation';
|
||||||
|
import { initializeListeners } from 'react-navigation-redux-helpers';
|
||||||
|
|
||||||
import LoginScreen from '../components/LoginScreen';
|
import LoginScreen from '../components/LoginScreen';
|
||||||
import MainScreen from '../components/MainScreen';
|
import MainScreen from '../components/MainScreen';
|
||||||
@@ -20,6 +21,10 @@ class AppWithNavigationState extends React.Component {
|
|||||||
nav: PropTypes.object.isRequired,
|
nav: PropTypes.object.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
initializeListeners('root', this.props.nav);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { dispatch, nav } = this.props;
|
const { dispatch, nav } = this.props;
|
||||||
return (
|
return (
|
||||||
|
|||||||
18
flow/react-navigation.js
vendored
18
flow/react-navigation.js
vendored
@@ -295,7 +295,6 @@ declare module 'react-navigation' {
|
|||||||
} & NavigationScreenRouteConfig);
|
} & NavigationScreenRouteConfig);
|
||||||
|
|
||||||
declare export type NavigationScreenRouteConfig =
|
declare export type NavigationScreenRouteConfig =
|
||||||
| NavigationComponent
|
|
||||||
| {
|
| {
|
||||||
screen: NavigationComponent,
|
screen: NavigationComponent,
|
||||||
}
|
}
|
||||||
@@ -361,6 +360,7 @@ declare module 'react-navigation' {
|
|||||||
initialRouteParams?: NavigationParams,
|
initialRouteParams?: NavigationParams,
|
||||||
paths?: NavigationPathsConfig,
|
paths?: NavigationPathsConfig,
|
||||||
navigationOptions?: NavigationScreenConfig<*>,
|
navigationOptions?: NavigationScreenConfig<*>,
|
||||||
|
initialRouteKey?: string,
|
||||||
|};
|
|};
|
||||||
|
|
||||||
declare export type NavigationStackViewConfig = {|
|
declare export type NavigationStackViewConfig = {|
|
||||||
@@ -470,7 +470,7 @@ declare module 'react-navigation' {
|
|||||||
type: EventType,
|
type: EventType,
|
||||||
action: NavigationAction,
|
action: NavigationAction,
|
||||||
state: NavigationState,
|
state: NavigationState,
|
||||||
lastState: NavigationState,
|
lastState: ?NavigationState,
|
||||||
};
|
};
|
||||||
|
|
||||||
declare export type NavigationEventCallback = (
|
declare export type NavigationEventCallback = (
|
||||||
@@ -553,7 +553,7 @@ declare module 'react-navigation' {
|
|||||||
|
|
||||||
declare export type NavigationContainerProps<S: {}, O: {}> = $Shape<{
|
declare export type NavigationContainerProps<S: {}, O: {}> = $Shape<{
|
||||||
uriPrefix?: string | RegExp,
|
uriPrefix?: string | RegExp,
|
||||||
onNavigationStateChange?: (
|
onNavigationStateChange?: ?(
|
||||||
NavigationState,
|
NavigationState,
|
||||||
NavigationState,
|
NavigationState,
|
||||||
NavigationAction
|
NavigationAction
|
||||||
@@ -724,7 +724,7 @@ declare module 'react-navigation' {
|
|||||||
SET_PARAMS: 'Navigation/SET_PARAMS',
|
SET_PARAMS: 'Navigation/SET_PARAMS',
|
||||||
URI: 'Navigation/URI',
|
URI: 'Navigation/URI',
|
||||||
back: {
|
back: {
|
||||||
(payload: { key?: ?string }): NavigationBackAction,
|
(payload?: { key?: ?string }): NavigationBackAction,
|
||||||
toString: () => string,
|
toString: () => string,
|
||||||
},
|
},
|
||||||
init: {
|
init: {
|
||||||
@@ -925,12 +925,14 @@ declare module 'react-navigation' {
|
|||||||
vertical?: _SafeAreaViewForceInsetValue,
|
vertical?: _SafeAreaViewForceInsetValue,
|
||||||
horizontal?: _SafeAreaViewForceInsetValue,
|
horizontal?: _SafeAreaViewForceInsetValue,
|
||||||
},
|
},
|
||||||
children: React$Node,
|
children?: React$Node,
|
||||||
style?: AnimatedViewStyleProp,
|
style?: AnimatedViewStyleProp,
|
||||||
};
|
};
|
||||||
declare export var SafeAreaView: React$ComponentType<_SafeAreaViewProps>;
|
declare export var SafeAreaView: React$ComponentType<_SafeAreaViewProps>;
|
||||||
|
|
||||||
declare export var Header: React$ComponentType<HeaderProps>;
|
declare export var Header: React$ComponentType<HeaderProps> & {
|
||||||
|
HEIGHT: number,
|
||||||
|
};
|
||||||
|
|
||||||
declare type _HeaderTitleProps = {
|
declare type _HeaderTitleProps = {
|
||||||
children: React$Node,
|
children: React$Node,
|
||||||
@@ -995,6 +997,8 @@ declare module 'react-navigation' {
|
|||||||
itemsContainerStyle?: ViewStyleProp,
|
itemsContainerStyle?: ViewStyleProp,
|
||||||
itemStyle?: ViewStyleProp,
|
itemStyle?: ViewStyleProp,
|
||||||
labelStyle?: TextStyleProp,
|
labelStyle?: TextStyleProp,
|
||||||
|
activeLabelStyle?: TextStyleProp,
|
||||||
|
inactiveLabelStyle?: TextStyleProp,
|
||||||
iconContainerStyle?: ViewStyleProp,
|
iconContainerStyle?: ViewStyleProp,
|
||||||
drawerPosition: 'left' | 'right',
|
drawerPosition: 'left' | 'right',
|
||||||
};
|
};
|
||||||
@@ -1075,7 +1079,7 @@ declare module 'react-navigation' {
|
|||||||
declare export var TabBarBottom: React$ComponentType<_TabBarBottomProps>;
|
declare export var TabBarBottom: React$ComponentType<_TabBarBottomProps>;
|
||||||
|
|
||||||
declare type _NavigationInjectedProps = {
|
declare type _NavigationInjectedProps = {
|
||||||
navigation: NavigationScreenProp<NavigationState>,
|
navigation: NavigationScreenProp<NavigationStateRoute>,
|
||||||
};
|
};
|
||||||
declare export function withNavigation<T: {}>(
|
declare export function withNavigation<T: {}>(
|
||||||
Component: React$ComponentType<T & _NavigationInjectedProps>
|
Component: React$ComponentType<T & _NavigationInjectedProps>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-navigation",
|
"name": "react-navigation",
|
||||||
"version": "1.4.0",
|
"version": "1.5.6",
|
||||||
"description": "Routing and navigation for your React Native apps",
|
"description": "Routing and navigation for your React Native apps",
|
||||||
"main": "src/react-navigation.js",
|
"main": "src/react-navigation.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
@@ -32,6 +32,7 @@
|
|||||||
"hoist-non-react-statics": "^2.2.0",
|
"hoist-non-react-statics": "^2.2.0",
|
||||||
"path-to-regexp": "^1.7.0",
|
"path-to-regexp": "^1.7.0",
|
||||||
"prop-types": "^15.5.10",
|
"prop-types": "^15.5.10",
|
||||||
|
"react-lifecycles-compat": "^1.0.2",
|
||||||
"react-native-drawer-layout-polyfill": "^1.3.2",
|
"react-native-drawer-layout-polyfill": "^1.3.2",
|
||||||
"react-native-safe-area-view": "^0.7.0",
|
"react-native-safe-area-view": "^0.7.0",
|
||||||
"react-native-tab-view": "^0.0.74"
|
"react-native-tab-view": "^0.0.74"
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import NavigationActions from '../NavigationActions';
|
|||||||
|
|
||||||
export default (routeConfigMap, stackConfig = {}) => {
|
export default (routeConfigMap, stackConfig = {}) => {
|
||||||
const {
|
const {
|
||||||
|
initialRouteKey,
|
||||||
initialRouteName,
|
initialRouteName,
|
||||||
initialRouteParams,
|
initialRouteParams,
|
||||||
paths,
|
paths,
|
||||||
@@ -25,6 +26,7 @@ export default (routeConfigMap, stackConfig = {}) => {
|
|||||||
} = stackConfig;
|
} = stackConfig;
|
||||||
|
|
||||||
const stackRouterConfig = {
|
const stackRouterConfig = {
|
||||||
|
initialRouteKey,
|
||||||
initialRouteName,
|
initialRouteName,
|
||||||
initialRouteParams,
|
initialRouteParams,
|
||||||
paths,
|
paths,
|
||||||
@@ -47,7 +49,7 @@ export default (routeConfigMap, stackConfig = {}) => {
|
|||||||
onTransitionEnd={(lastTransition, transition) => {
|
onTransitionEnd={(lastTransition, transition) => {
|
||||||
const { state, dispatch } = props.navigation;
|
const { state, dispatch } = props.navigation;
|
||||||
dispatch(NavigationActions.completeTransition({ key: state.key }));
|
dispatch(NavigationActions.completeTransition({ key: state.key }));
|
||||||
onTransitionEnd && onTransitionEnd();
|
onTransitionEnd && onTransitionEnd(lastTransition, transition);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -224,6 +224,7 @@ exports[`DrawerNavigator renders successfully 1`] = `
|
|||||||
"color": "#2196f3",
|
"color": "#2196f3",
|
||||||
},
|
},
|
||||||
undefined,
|
undefined,
|
||||||
|
undefined,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -137,9 +137,12 @@ exports[`TabNavigator renders successfully 1`] = `
|
|||||||
>
|
>
|
||||||
<View
|
<View
|
||||||
style={
|
style={
|
||||||
Object {
|
Array [
|
||||||
"flexGrow": 1,
|
false,
|
||||||
}
|
Object {
|
||||||
|
"flexGrow": 1,
|
||||||
|
},
|
||||||
|
]
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<View
|
<View
|
||||||
@@ -147,13 +150,12 @@ exports[`TabNavigator renders successfully 1`] = `
|
|||||||
style={
|
style={
|
||||||
Object {
|
Object {
|
||||||
"alignItems": "center",
|
"alignItems": "center",
|
||||||
"bottom": 0,
|
"alignSelf": "center",
|
||||||
|
"height": "100%",
|
||||||
"justifyContent": "center",
|
"justifyContent": "center",
|
||||||
"left": 0,
|
|
||||||
"opacity": 1,
|
"opacity": 1,
|
||||||
"position": "absolute",
|
"position": "absolute",
|
||||||
"right": 0,
|
"width": "100%",
|
||||||
"top": 0,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
@@ -162,13 +164,12 @@ exports[`TabNavigator renders successfully 1`] = `
|
|||||||
style={
|
style={
|
||||||
Object {
|
Object {
|
||||||
"alignItems": "center",
|
"alignItems": "center",
|
||||||
"bottom": 0,
|
"alignSelf": "center",
|
||||||
|
"height": "100%",
|
||||||
"justifyContent": "center",
|
"justifyContent": "center",
|
||||||
"left": 0,
|
|
||||||
"opacity": 0,
|
"opacity": 0,
|
||||||
"position": "absolute",
|
"position": "absolute",
|
||||||
"right": 0,
|
"width": "100%",
|
||||||
"top": 0,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -92,11 +92,12 @@ export default (routeConfigs, stackConfig = {}) => {
|
|||||||
...(action.params || {}),
|
...(action.params || {}),
|
||||||
...(initialRouteParams || {}),
|
...(initialRouteParams || {}),
|
||||||
};
|
};
|
||||||
|
const { initialRouteKey } = stackConfig;
|
||||||
route = {
|
route = {
|
||||||
...route,
|
...route,
|
||||||
...(params ? { params } : {}),
|
...(params ? { params } : {}),
|
||||||
routeName: initialRouteName,
|
routeName: initialRouteName,
|
||||||
key: action.key || generateKey(),
|
key: action.key || (initialRouteKey || generateKey()),
|
||||||
};
|
};
|
||||||
return {
|
return {
|
||||||
key: 'StackRouterRoot',
|
key: 'StackRouterRoot',
|
||||||
|
|||||||
@@ -576,6 +576,23 @@ describe('StackRouter', () => {
|
|||||||
expect(state2.routes[1].routes[1].routes[1].routeName).toEqual('Corge');
|
expect(state2.routes[1].routes[1].routes[1].routeName).toEqual('Corge');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Navigate to initial screen is possible', () => {
|
||||||
|
const TestRouter = StackRouter(
|
||||||
|
{
|
||||||
|
foo: { screen: () => <div /> },
|
||||||
|
bar: { screen: () => <div /> },
|
||||||
|
},
|
||||||
|
{ initialRouteKey: 'foo' }
|
||||||
|
);
|
||||||
|
const initState = TestRouter.getStateForAction(NavigationActions.init());
|
||||||
|
const pushedState = TestRouter.getStateForAction(
|
||||||
|
NavigationActions.navigate({ routeName: 'foo', key: 'foo' }),
|
||||||
|
initState
|
||||||
|
);
|
||||||
|
expect(pushedState.index).toEqual(0);
|
||||||
|
expect(pushedState.routes[0].routeName).toEqual('foo');
|
||||||
|
});
|
||||||
|
|
||||||
test('Navigate with key is idempotent', () => {
|
test('Navigate with key is idempotent', () => {
|
||||||
const TestRouter = StackRouter({
|
const TestRouter = StackRouter({
|
||||||
foo: { screen: () => <div /> },
|
foo: { screen: () => <div /> },
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ class CardStack extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_isRouteFocused = route => {
|
_isRouteFocused = route => {
|
||||||
const { state } = this.props.navigation;
|
const { transitionProps: { navigation: { state } } } = this.props;
|
||||||
const focusedRoute = state.routes[state.index];
|
const focusedRoute = state.routes[state.index];
|
||||||
return route === focusedRoute;
|
return route === focusedRoute;
|
||||||
};
|
};
|
||||||
@@ -129,7 +129,7 @@ class CardStack extends React.Component {
|
|||||||
const screenNavigation = addNavigationHelpers({
|
const screenNavigation = addNavigationHelpers({
|
||||||
dispatch: navigation.dispatch,
|
dispatch: navigation.dispatch,
|
||||||
state: scene.route,
|
state: scene.route,
|
||||||
isFocused: this._isRouteFocused.bind(this, scene.route),
|
isFocused: () => this._isRouteFocused(scene.route),
|
||||||
addListener: this._childEventSubscribers[scene.route.key],
|
addListener: this._childEventSubscribers[scene.route.key],
|
||||||
});
|
});
|
||||||
screenDetails = {
|
screenDetails = {
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ const DrawerNavigatorItems = ({
|
|||||||
itemsContainerStyle,
|
itemsContainerStyle,
|
||||||
itemStyle,
|
itemStyle,
|
||||||
labelStyle,
|
labelStyle,
|
||||||
|
activeLabelStyle,
|
||||||
|
inactiveLabelStyle,
|
||||||
iconContainerStyle,
|
iconContainerStyle,
|
||||||
drawerPosition,
|
drawerPosition,
|
||||||
}) => (
|
}) => (
|
||||||
@@ -34,6 +36,7 @@ const DrawerNavigatorItems = ({
|
|||||||
const scene = { route, index, focused, tintColor: color };
|
const scene = { route, index, focused, tintColor: color };
|
||||||
const icon = renderIcon(scene);
|
const icon = renderIcon(scene);
|
||||||
const label = getLabel(scene);
|
const label = getLabel(scene);
|
||||||
|
const extraLabelStyle = focused ? activeLabelStyle : inactiveLabelStyle;
|
||||||
return (
|
return (
|
||||||
<TouchableItem
|
<TouchableItem
|
||||||
key={route.key}
|
key={route.key}
|
||||||
@@ -63,7 +66,9 @@ const DrawerNavigatorItems = ({
|
|||||||
</View>
|
</View>
|
||||||
) : null}
|
) : null}
|
||||||
{typeof label === 'string' ? (
|
{typeof label === 'string' ? (
|
||||||
<Text style={[styles.label, { color }, labelStyle]}>
|
<Text
|
||||||
|
style={[styles.label, { color }, labelStyle, extraLabelStyle]}
|
||||||
|
>
|
||||||
{label}
|
{label}
|
||||||
</Text>
|
</Text>
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ export default class DrawerView extends React.PureComponent {
|
|||||||
this._screenNavigationProp = addNavigationHelpers({
|
this._screenNavigationProp = addNavigationHelpers({
|
||||||
dispatch: navigation.dispatch,
|
dispatch: navigation.dispatch,
|
||||||
state: navigationState,
|
state: navigationState,
|
||||||
isFocused: this._isRouteFocused.bind(this, navigationState),
|
isFocused: () => this._isRouteFocused(navigationState),
|
||||||
addListener: this._childEventSubscribers[navigationState.key],
|
addListener: this._childEventSubscribers[navigationState.key],
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,40 +1,33 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Platform, StyleSheet, View } from 'react-native';
|
import { Platform, StyleSheet, View } from 'react-native';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import withLifecyclePolyfill from 'react-lifecycles-compat';
|
||||||
|
|
||||||
import SceneView from './SceneView';
|
import SceneView from './SceneView';
|
||||||
|
|
||||||
const FAR_FAR_AWAY = 3000; // this should be big enough to move the whole view out of its container
|
const FAR_FAR_AWAY = 3000; // this should be big enough to move the whole view out of its container
|
||||||
|
|
||||||
export default class ResourceSavingSceneView extends React.PureComponent {
|
class ResourceSavingSceneView extends React.PureComponent {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
const key = props.childNavigation.state.key;
|
|
||||||
const focusedIndex = props.navigation.state.index;
|
|
||||||
const focusedKey = props.navigation.state.routes[focusedIndex].key;
|
|
||||||
const isFocused = key === focusedKey;
|
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
awake: props.lazy ? isFocused : true,
|
awake: props.lazy ? props.isFocused : true,
|
||||||
visible: isFocused,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillMount() {
|
static getDerivedStateFromProps(nextProps, prevState) {
|
||||||
this._actionListener = this.props.navigation.addListener(
|
if (nextProps.isFocused && !prevState.awake) {
|
||||||
'action',
|
return { awake: true };
|
||||||
this._onAction
|
}
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
return null;
|
||||||
this._actionListener.remove();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { awake, visible } = this.state;
|
const { awake } = this.state;
|
||||||
const {
|
const {
|
||||||
|
isFocused,
|
||||||
childNavigation,
|
childNavigation,
|
||||||
navigation,
|
navigation,
|
||||||
removeClippedSubviews,
|
removeClippedSubviews,
|
||||||
@@ -49,12 +42,12 @@ export default class ResourceSavingSceneView extends React.PureComponent {
|
|||||||
removeClippedSubviews={
|
removeClippedSubviews={
|
||||||
Platform.OS === 'android'
|
Platform.OS === 'android'
|
||||||
? removeClippedSubviews
|
? removeClippedSubviews
|
||||||
: !visible && removeClippedSubviews
|
: !isFocused && removeClippedSubviews
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<View
|
<View
|
||||||
style={
|
style={
|
||||||
this._mustAlwaysBeVisible() || visible
|
this._mustAlwaysBeVisible() || isFocused
|
||||||
? styles.innerAttached
|
? styles.innerAttached
|
||||||
: styles.innerDetached
|
: styles.innerDetached
|
||||||
}
|
}
|
||||||
@@ -68,33 +61,6 @@ export default class ResourceSavingSceneView extends React.PureComponent {
|
|||||||
_mustAlwaysBeVisible = () => {
|
_mustAlwaysBeVisible = () => {
|
||||||
return this.props.animationEnabled || this.props.swipeEnabled;
|
return this.props.animationEnabled || this.props.swipeEnabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
_onAction = payload => {
|
|
||||||
// We do not care about transition complete events, they won't actually change the state
|
|
||||||
if (
|
|
||||||
payload.action.type == 'Navigation/COMPLETE_TRANSITION' ||
|
|
||||||
!payload.state
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { routes, index } = payload.state;
|
|
||||||
const key = this.props.childNavigation.state.key;
|
|
||||||
|
|
||||||
if (routes[index].key === key) {
|
|
||||||
if (!this.state.visible) {
|
|
||||||
let nextState = { visible: true };
|
|
||||||
if (!this.state.awake) {
|
|
||||||
nextState.awake = true;
|
|
||||||
}
|
|
||||||
this.setState(nextState);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (this.state.visible) {
|
|
||||||
this.setState({ visible: false });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
@@ -110,3 +76,5 @@ const styles = StyleSheet.create({
|
|||||||
top: FAR_FAR_AWAY,
|
top: FAR_FAR_AWAY,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export default withLifecyclePolyfill(ResourceSavingSceneView);
|
||||||
|
|||||||
@@ -100,6 +100,9 @@ class TabBarBottom extends React.PureComponent {
|
|||||||
if (showIcon === false) {
|
if (showIcon === false) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const horizontal = this._shouldUseHorizontalTabs();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TabBarIcon
|
<TabBarIcon
|
||||||
position={position}
|
position={position}
|
||||||
@@ -108,7 +111,10 @@ class TabBarBottom extends React.PureComponent {
|
|||||||
inactiveTintColor={inactiveTintColor}
|
inactiveTintColor={inactiveTintColor}
|
||||||
renderIcon={renderIcon}
|
renderIcon={renderIcon}
|
||||||
scene={scene}
|
scene={scene}
|
||||||
style={showLabel && this._shouldUseHorizontalTabs() ? {} : styles.icon}
|
style={[
|
||||||
|
horizontal && styles.horizontalIcon,
|
||||||
|
showLabel !== false && !horizontal && styles.icon,
|
||||||
|
]}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -286,6 +292,9 @@ class TabBarBottom extends React.PureComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const DEFAULT_HEIGHT = 49;
|
||||||
|
const COMPACT_HEIGHT = 29;
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
tabBar: {
|
tabBar: {
|
||||||
backgroundColor: '#F7F7F7', // Default background color in iOS 10
|
backgroundColor: '#F7F7F7', // Default background color in iOS 10
|
||||||
@@ -294,10 +303,10 @@ const styles = StyleSheet.create({
|
|||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
},
|
},
|
||||||
tabBarCompact: {
|
tabBarCompact: {
|
||||||
height: 29,
|
height: COMPACT_HEIGHT,
|
||||||
},
|
},
|
||||||
tabBarRegular: {
|
tabBarRegular: {
|
||||||
height: 49,
|
height: DEFAULT_HEIGHT,
|
||||||
},
|
},
|
||||||
tab: {
|
tab: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
@@ -314,6 +323,9 @@ const styles = StyleSheet.create({
|
|||||||
icon: {
|
icon: {
|
||||||
flexGrow: 1,
|
flexGrow: 1,
|
||||||
},
|
},
|
||||||
|
horizontalIcon: {
|
||||||
|
height: Platform.isPad ? DEFAULT_HEIGHT : COMPACT_HEIGHT,
|
||||||
|
},
|
||||||
label: {
|
label: {
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
backgroundColor: 'transparent',
|
backgroundColor: 'transparent',
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ export default class TabBarIcon extends React.PureComponent {
|
|||||||
inputRange,
|
inputRange,
|
||||||
outputRange: inputRange.map(i => (i === index ? 0 : 1)),
|
outputRange: inputRange.map(i => (i === index ? 0 : 1)),
|
||||||
});
|
});
|
||||||
|
|
||||||
// We render the icon twice at the same position on top of each other:
|
// We render the icon twice at the same position on top of each other:
|
||||||
// active and inactive one, so we can fade between them.
|
// active and inactive one, so we can fade between them.
|
||||||
return (
|
return (
|
||||||
@@ -53,12 +54,11 @@ const styles = StyleSheet.create({
|
|||||||
// We render the icon twice at the same position on top of each other:
|
// We render the icon twice at the same position on top of each other:
|
||||||
// active and inactive one, so we can fade between them:
|
// active and inactive one, so we can fade between them:
|
||||||
// Cover the whole iconContainer:
|
// Cover the whole iconContainer:
|
||||||
position: 'absolute',
|
|
||||||
top: 0,
|
|
||||||
left: 0,
|
|
||||||
right: 0,
|
|
||||||
bottom: 0,
|
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
|
alignSelf: 'center',
|
||||||
|
height: '100%',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
|
position: 'absolute',
|
||||||
|
width: '100%',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -22,7 +22,10 @@ class TabView extends React.PureComponent {
|
|||||||
};
|
};
|
||||||
|
|
||||||
_renderScene = ({ route }) => {
|
_renderScene = ({ route }) => {
|
||||||
const { screenProps } = this.props;
|
const { screenProps, navigation } = this.props;
|
||||||
|
const focusedIndex = navigation.state.index;
|
||||||
|
const focusedKey = navigation.state.routes[focusedIndex].key;
|
||||||
|
const key = route.key;
|
||||||
const childNavigation = this.props.childNavigationProps[route.key];
|
const childNavigation = this.props.childNavigationProps[route.key];
|
||||||
const TabComponent = this.props.router.getComponentForRouteName(
|
const TabComponent = this.props.router.getComponentForRouteName(
|
||||||
route.routeName
|
route.routeName
|
||||||
@@ -31,6 +34,7 @@ class TabView extends React.PureComponent {
|
|||||||
return (
|
return (
|
||||||
<ResourceSavingSceneView
|
<ResourceSavingSceneView
|
||||||
lazy={this.props.lazy}
|
lazy={this.props.lazy}
|
||||||
|
isFocused={focusedKey === key}
|
||||||
removeClippedSubViews={this.props.removeClippedSubviews}
|
removeClippedSubViews={this.props.removeClippedSubviews}
|
||||||
animationEnabled={this.props.animationEnabled}
|
animationEnabled={this.props.animationEnabled}
|
||||||
swipeEnabled={this.props.swipeEnabled}
|
swipeEnabled={this.props.swipeEnabled}
|
||||||
|
|||||||
@@ -83,9 +83,12 @@ exports[`TabBarBottom renders successfully 1`] = `
|
|||||||
>
|
>
|
||||||
<View
|
<View
|
||||||
style={
|
style={
|
||||||
Object {
|
Array [
|
||||||
"flexGrow": 1,
|
false,
|
||||||
}
|
Object {
|
||||||
|
"flexGrow": 1,
|
||||||
|
},
|
||||||
|
]
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<View
|
<View
|
||||||
@@ -93,13 +96,12 @@ exports[`TabBarBottom renders successfully 1`] = `
|
|||||||
style={
|
style={
|
||||||
Object {
|
Object {
|
||||||
"alignItems": "center",
|
"alignItems": "center",
|
||||||
"bottom": 0,
|
"alignSelf": "center",
|
||||||
|
"height": "100%",
|
||||||
"justifyContent": "center",
|
"justifyContent": "center",
|
||||||
"left": 0,
|
|
||||||
"opacity": 1,
|
"opacity": 1,
|
||||||
"position": "absolute",
|
"position": "absolute",
|
||||||
"right": 0,
|
"width": "100%",
|
||||||
"top": 0,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
@@ -108,13 +110,12 @@ exports[`TabBarBottom renders successfully 1`] = `
|
|||||||
style={
|
style={
|
||||||
Object {
|
Object {
|
||||||
"alignItems": "center",
|
"alignItems": "center",
|
||||||
"bottom": 0,
|
"alignSelf": "center",
|
||||||
|
"height": "100%",
|
||||||
"justifyContent": "center",
|
"justifyContent": "center",
|
||||||
"left": 0,
|
|
||||||
"opacity": 0,
|
"opacity": 0,
|
||||||
"position": "absolute",
|
"position": "absolute",
|
||||||
"right": 0,
|
"width": "100%",
|
||||||
"top": 0,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export default function withCachedChildNavigation(Comp) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_isRouteFocused = route => () => {
|
_isRouteFocused = route => {
|
||||||
const { state } = this.props.navigation;
|
const { state } = this.props.navigation;
|
||||||
const focusedRoute = state.routes[state.index];
|
const focusedRoute = state.routes[state.index];
|
||||||
return route === focusedRoute;
|
return route === focusedRoute;
|
||||||
@@ -58,7 +58,7 @@ export default function withCachedChildNavigation(Comp) {
|
|||||||
this._childNavigationProps[route.key] = addNavigationHelpers({
|
this._childNavigationProps[route.key] = addNavigationHelpers({
|
||||||
dispatch: navigation.dispatch,
|
dispatch: navigation.dispatch,
|
||||||
state: route,
|
state: route,
|
||||||
isFocused: this._isRouteFocused.bind(this, route),
|
isFocused: () => this._isRouteFocused(route),
|
||||||
addListener: this._childEventSubscribers[route.key],
|
addListener: this._childEventSubscribers[route.key],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4424,6 +4424,10 @@ react-devtools-core@3.0.0:
|
|||||||
shell-quote "^1.6.1"
|
shell-quote "^1.6.1"
|
||||||
ws "^2.0.3"
|
ws "^2.0.3"
|
||||||
|
|
||||||
|
react-lifecycles-compat@^1.0.2:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-1.0.2.tgz#551d8b1d156346e5fcf30ffac9b32ce3f78b8850"
|
||||||
|
|
||||||
react-native-dismiss-keyboard@1.0.0:
|
react-native-dismiss-keyboard@1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/react-native-dismiss-keyboard/-/react-native-dismiss-keyboard-1.0.0.tgz#32886242b3f2317e121f3aeb9b0a585e2b879b49"
|
resolved "https://registry.yarnpkg.com/react-native-dismiss-keyboard/-/react-native-dismiss-keyboard-1.0.0.tgz#32886242b3f2317e121f3aeb9b0a585e2b879b49"
|
||||||
|
|||||||
Reference in New Issue
Block a user