mirror of
https://github.com/zhigang1992/react-navigation.git
synced 2026-03-27 22:56:07 +08:00
Drawer Improvement, Let define a route key to open/close multiple dra… (#1803)
* Drawer Improvement, Let define a route key to open/close multiple drawer with no side effects * fix lint issues * fix flow issues
This commit is contained in:
@@ -19,6 +19,7 @@ import Banner from './Banner';
|
||||
import CustomTabs from './CustomTabs';
|
||||
import CustomTransitioner from './CustomTransitioner';
|
||||
import Drawer from './Drawer';
|
||||
import MultipleDrawer from './MultipleDrawer';
|
||||
import TabsInDrawer from './TabsInDrawer';
|
||||
import ModalStack from './ModalStack';
|
||||
import StacksInTabs from './StacksInTabs';
|
||||
@@ -43,6 +44,11 @@ const ExampleRoutes = {
|
||||
description: 'Android-style drawer navigation',
|
||||
screen: Drawer,
|
||||
},
|
||||
MultipleDrawer: {
|
||||
name: 'Multiple Drawer Example',
|
||||
description: 'Add any drawer you need',
|
||||
screen: MultipleDrawer,
|
||||
},
|
||||
TabsInDrawer: {
|
||||
name: 'Drawer + Tabs Example',
|
||||
description: 'A drawer combined with tabs',
|
||||
|
||||
80
packages/react-navigation/examples/NavigationPlayground/js/MultipleDrawer.js
vendored
Normal file
80
packages/react-navigation/examples/NavigationPlayground/js/MultipleDrawer.js
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Button, Platform, ScrollView, StyleSheet } from 'react-native';
|
||||
import { DrawerNavigator } from 'react-navigation';
|
||||
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
|
||||
import SampleText from './SampleText';
|
||||
|
||||
const MyNavScreen = ({ navigation, banner }) => (
|
||||
<ScrollView style={styles.container}>
|
||||
<SampleText>{banner}</SampleText>
|
||||
<Button
|
||||
onPress={() => navigation.navigate('DrawerOpen')}
|
||||
title="Open drawer"
|
||||
/>
|
||||
<Button onPress={() => navigation.goBack(null)} title="Go back" />
|
||||
</ScrollView>
|
||||
);
|
||||
|
||||
const InboxScreen = ({ navigation }) => (
|
||||
<MyNavScreen banner={'Inbox Screen'} navigation={navigation} />
|
||||
);
|
||||
InboxScreen.navigationOptions = {
|
||||
drawerLabel: 'Inbox',
|
||||
drawerIcon: ({ tintColor }) => (
|
||||
<MaterialIcons
|
||||
name="move-to-inbox"
|
||||
size={24}
|
||||
style={{ color: tintColor }}
|
||||
/>
|
||||
),
|
||||
};
|
||||
|
||||
const DraftsScreen = ({ navigation }) => (
|
||||
<MyNavScreen banner={'Drafts Screen'} navigation={navigation} />
|
||||
);
|
||||
DraftsScreen.navigationOptions = {
|
||||
drawerLabel: 'Drafts',
|
||||
drawerIcon: ({ tintColor }) => (
|
||||
<MaterialIcons name="drafts" size={24} style={{ color: tintColor }} />
|
||||
),
|
||||
};
|
||||
|
||||
const DrawerExample = DrawerNavigator(
|
||||
{
|
||||
Inbox: {
|
||||
path: '/',
|
||||
screen: InboxScreen,
|
||||
},
|
||||
Drafts: {
|
||||
path: '/sent',
|
||||
screen: DraftsScreen,
|
||||
},
|
||||
},
|
||||
{
|
||||
initialRouteName: 'Drafts',
|
||||
contentOptions: {
|
||||
activeTintColor: '#e91e63',
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const MainDrawerExample = DrawerNavigator({
|
||||
Drafts: {
|
||||
screen: DrawerExample,
|
||||
},
|
||||
}, {
|
||||
drawerOpenRoute: 'FooDrawerOpen',
|
||||
drawerCloseRoute: 'FooDrawerClose',
|
||||
});
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
marginTop: Platform.OS === 'ios' ? 20 : 0,
|
||||
},
|
||||
});
|
||||
|
||||
export default MainDrawerExample;
|
||||
@@ -70,7 +70,11 @@ const DefaultDrawerConfig = {
|
||||
|
||||
const DrawerNavigator = (
|
||||
routeConfigs: NavigationRouteConfigMap,
|
||||
config: DrawerNavigatorConfig = {}
|
||||
config: DrawerNavigatorConfig = {
|
||||
drawerOpenRoute: 'DrawerOpen',
|
||||
drawerCloseRoute: 'DrawerClose',
|
||||
drawerToggleRoute: 'DrawerToggle',
|
||||
}
|
||||
) => {
|
||||
const mergedConfig = { ...DefaultDrawerConfig, ...config };
|
||||
const {
|
||||
@@ -82,6 +86,9 @@ const DrawerNavigator = (
|
||||
drawerPosition,
|
||||
useNativeAnimations,
|
||||
drawerBackgroundColor,
|
||||
drawerOpenRoute,
|
||||
drawerCloseRoute,
|
||||
drawerToggleRoute,
|
||||
...tabsConfig
|
||||
} = mergedConfig;
|
||||
|
||||
@@ -89,7 +96,7 @@ const DrawerNavigator = (
|
||||
|
||||
const drawerRouter = TabRouter(
|
||||
{
|
||||
DrawerClose: {
|
||||
[drawerCloseRoute]: {
|
||||
screen: createNavigator(
|
||||
contentRouter,
|
||||
routeConfigs,
|
||||
@@ -99,15 +106,15 @@ const DrawerNavigator = (
|
||||
<DrawerScreen {...props} />
|
||||
)),
|
||||
},
|
||||
DrawerOpen: {
|
||||
[drawerOpenRoute]: {
|
||||
screen: () => null,
|
||||
},
|
||||
DrawerToggle: {
|
||||
[drawerToggleRoute]: {
|
||||
screen: () => null,
|
||||
},
|
||||
},
|
||||
{
|
||||
initialRouteName: 'DrawerClose',
|
||||
initialRouteName: drawerCloseRoute,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -126,6 +133,9 @@ const DrawerNavigator = (
|
||||
contentComponent={contentComponent}
|
||||
contentOptions={contentOptions}
|
||||
drawerPosition={drawerPosition}
|
||||
drawerOpenRoute={drawerOpenRoute}
|
||||
drawerCloseRoute={drawerCloseRoute}
|
||||
drawerToggleRoute={drawerToggleRoute}
|
||||
/>
|
||||
));
|
||||
|
||||
|
||||
@@ -33,6 +33,9 @@ export type DrawerViewConfig = {
|
||||
drawerLockMode?: 'unlocked' | 'locked-closed' | 'locked-open',
|
||||
drawerWidth?: number | (() => number),
|
||||
drawerPosition?: 'left' | 'right',
|
||||
drawerOpenRoute: string,
|
||||
drawerCloseRoute: string,
|
||||
drawerToggleRoute: string,
|
||||
contentComponent?: React.ComponentType<*>,
|
||||
contentOptions?: {},
|
||||
style?: ViewStyleProp,
|
||||
@@ -81,14 +84,19 @@ export default class DrawerView extends React.PureComponent<
|
||||
if (
|
||||
this.props.navigation.state.index !== nextProps.navigation.state.index
|
||||
) {
|
||||
const {
|
||||
drawerOpenRoute,
|
||||
drawerCloseRoute,
|
||||
drawerToggleRoute,
|
||||
} = this.props;
|
||||
const { routes, index } = nextProps.navigation.state;
|
||||
if (routes[index].routeName === 'DrawerOpen') {
|
||||
if (routes[index].routeName === drawerOpenRoute) {
|
||||
this._drawer.openDrawer();
|
||||
} else if (routes[index].routeName === 'DrawerToggle') {
|
||||
} else if (routes[index].routeName === drawerToggleRoute) {
|
||||
if (this._drawer.state.drawerShown) {
|
||||
this.props.navigation.navigate('DrawerClose');
|
||||
this.props.navigation.navigate(drawerCloseRoute);
|
||||
} else {
|
||||
this.props.navigation.navigate('DrawerOpen');
|
||||
this.props.navigation.navigate(drawerOpenRoute);
|
||||
}
|
||||
} else {
|
||||
this._drawer.closeDrawer();
|
||||
@@ -100,27 +108,28 @@ export default class DrawerView extends React.PureComponent<
|
||||
_screenNavigationProp: NavigationScreenProp<NavigationStateRoute>;
|
||||
|
||||
_handleDrawerOpen = () => {
|
||||
const { navigation } = this.props;
|
||||
const { navigation, drawerOpenRoute } = this.props;
|
||||
const { routes, index } = navigation.state;
|
||||
if (routes[index].routeName !== 'DrawerOpen') {
|
||||
this.props.navigation.navigate('DrawerOpen');
|
||||
if (routes[index].routeName !== drawerOpenRoute) {
|
||||
this.props.navigation.navigate(drawerOpenRoute);
|
||||
}
|
||||
};
|
||||
|
||||
_handleDrawerClose = () => {
|
||||
const { navigation } = this.props;
|
||||
const { navigation, drawerCloseRoute } = this.props;
|
||||
const { routes, index } = navigation.state;
|
||||
if (routes[index].routeName !== 'DrawerClose') {
|
||||
this.props.navigation.navigate('DrawerClose');
|
||||
if (routes[index].routeName !== drawerCloseRoute) {
|
||||
this.props.navigation.navigate(drawerCloseRoute);
|
||||
}
|
||||
};
|
||||
|
||||
_updateScreenNavigation = (
|
||||
navigation: NavigationScreenProp<NavigationState>
|
||||
) => {
|
||||
const { drawerCloseRoute } = this.props;
|
||||
// $FlowFixMe there's no way type the specific shape of the nav state
|
||||
const navigationState: NavigationStateRoute = navigation.state.routes.find(
|
||||
(route: *) => route.routeName === 'DrawerClose'
|
||||
(route: *) => route.routeName === drawerCloseRoute
|
||||
);
|
||||
if (
|
||||
this._screenNavigationProp &&
|
||||
@@ -146,8 +155,9 @@ export default class DrawerView extends React.PureComponent<
|
||||
};
|
||||
|
||||
_getNavigationState = (navigation: NavigationScreenProp<NavigationState>) => {
|
||||
const { drawerCloseRoute } = this.props;
|
||||
const navigationState = navigation.state.routes.find(
|
||||
(route: *) => route.routeName === 'DrawerClose'
|
||||
(route: *) => route.routeName === drawerCloseRoute
|
||||
);
|
||||
return navigationState;
|
||||
};
|
||||
@@ -168,7 +178,7 @@ export default class DrawerView extends React.PureComponent<
|
||||
|
||||
render() {
|
||||
const DrawerScreen = this.props.router.getComponentForRouteName(
|
||||
'DrawerClose'
|
||||
this.props.drawerCloseRoute
|
||||
);
|
||||
|
||||
const screenNavigation = addNavigationHelpers({
|
||||
|
||||
Reference in New Issue
Block a user