123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410 |
- /* @flow */
- import React from 'react';
- import { Asset, Constants, ScreenOrientation } from 'expo';
- ScreenOrientation.allow(ScreenOrientation.Orientation.ALL);
- import {
- Animated,
- Image,
- Platform,
- ScrollView,
- StyleSheet,
- TouchableOpacity,
- Text,
- StatusBar,
- View,
- } from 'react-native';
- import { SafeAreaView, createStackNavigator } from 'react-navigation';
- 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';
- import StacksOverTabs from './StacksOverTabs';
- import StacksOverTopTabs from './StacksOverTopTabs';
- import StacksWithKeys from './StacksWithKeys';
- import InactiveStack from './InactiveStack';
- import StackWithCustomHeaderBackImage from './StackWithCustomHeaderBackImage';
- import SimpleStack from './SimpleStack';
- import StackWithHeaderPreset from './StackWithHeaderPreset';
- import StackWithTranslucentHeader from './StackWithTranslucentHeader';
- import SimpleTabs from './SimpleTabs';
- import SwitchWithStacks from './SwitchWithStacks';
- import TabsWithNavigationFocus from './TabsWithNavigationFocus';
- import TabsWithNavigationEvents from './TabsWithNavigationEvents';
- import KeyboardHandlingExample from './KeyboardHandlingExample';
- const ExampleInfo = {
- SimpleStack: {
- name: 'Stack Example',
- description: 'A card stack',
- },
- SwitchWithStacks: {
- name: 'Switch between routes',
- description: 'Jump between routes',
- },
- InactiveStack: {
- name: 'Navigate idempotently to stacks in inactive routes',
- description:
- 'An inactive route in a stack should be given the opportunity to handle actions',
- },
- StackWithCustomHeaderBackImage: {
- name: 'Custom header back image',
- description: 'Stack with custom header back image',
- },
- SimpleTabs: {
- name: 'Tabs Example',
- description: 'Tabs following platform conventions',
- },
- Drawer: {
- name: 'Drawer Example',
- description: 'Android-style drawer navigation',
- },
- StackWithHeaderPreset: {
- name: 'UIKit-style Header Transitions',
- description: 'Masked back button and sliding header items. iOS only.',
- },
- StackWithTranslucentHeader: {
- name: 'Translucent Header',
- description: 'Render arbitrary translucent content in header background.',
- },
- // MultipleDrawer: {
- // name: 'Multiple Drawer Example',
- // description: 'Add any drawer you need',
- // },
- TabsInDrawer: {
- name: 'Drawer + Tabs Example',
- description: 'A drawer combined with tabs',
- },
- CustomTabs: {
- name: 'Custom Tabs',
- description: 'Custom tabs with tab router',
- },
- CustomTransitioner: {
- name: 'Custom Transitioner',
- description: 'Custom transitioner with stack router',
- },
- ModalStack: {
- name:
- Platform.OS === 'ios'
- ? 'Modal Stack Example'
- : 'Stack with Dynamic Header',
- description:
- Platform.OS === 'ios'
- ? 'Stack navigation with modals'
- : 'Dynamically showing and hiding the header',
- },
- StacksInTabs: {
- name: 'Stacks in Tabs',
- description: 'Nested stack navigation in tabs',
- },
- StacksOverTabs: {
- name: 'Stacks over Tabs',
- description: 'Nested stack navigation that pushes on top of tabs',
- },
- StacksOverTopTabs: {
- name: 'Stacks with non-standard header height',
- description: 'Tab navigator in stack with custom header heights',
- },
- StacksWithKeys: {
- name: 'Link in Stack with keys',
- description: 'Use keys to link between screens',
- },
- LinkStack: {
- name: 'Link in Stack',
- description: 'Deep linking into a route in stack',
- },
- LinkTabs: {
- name: 'Link to Settings Tab',
- description: 'Deep linking into a route in tab',
- },
- TabsWithNavigationFocus: {
- name: 'withNavigationFocus',
- description: 'Receive the focus prop to know when a screen is focused',
- },
- TabsWithNavigationEvents: {
- name: 'NavigationEvents',
- description:
- 'Declarative NavigationEvents component to subscribe to navigation events',
- },
- KeyboardHandlingExample: {
- name: 'Keyboard Handling Example',
- description:
- 'Demo automatic handling of keyboard showing/hiding inside StackNavigator',
- },
- };
- const ExampleRoutes = {
- SimpleStack,
- SwitchWithStacks,
- SimpleTabs: SimpleTabs,
- Drawer: Drawer,
- // MultipleDrawer: {
- // screen: MultipleDrawer,
- // },
- StackWithCustomHeaderBackImage: StackWithCustomHeaderBackImage,
- ...Platform.select({
- ios: {
- StackWithHeaderPreset: StackWithHeaderPreset,
- },
- android: {},
- }),
- StackWithTranslucentHeader: StackWithTranslucentHeader,
- TabsInDrawer: TabsInDrawer,
- CustomTabs: CustomTabs,
- CustomTransitioner: CustomTransitioner,
- ModalStack: ModalStack,
- StacksWithKeys: StacksWithKeys,
- StacksInTabs: StacksInTabs,
- StacksOverTabs: StacksOverTabs,
- StacksOverTopTabs: StacksOverTopTabs,
- LinkStack: {
- screen: SimpleStack,
- path: 'people/Jordan',
- },
- LinkTabs: {
- screen: SimpleTabs,
- path: 'settings',
- },
- TabsWithNavigationFocus,
- TabsWithNavigationEvents,
- KeyboardHandlingExample,
- // This is commented out because it's rarely useful
- // InactiveStack,
- };
- type State = {
- scrollY: Animated.Value,
- };
- class MainScreen extends React.Component<any, State> {
- state = {
- scrollY: new Animated.Value(0),
- };
- componentDidMount() {
- Asset.fromModule(
- require('react-navigation/src/views/assets/back-icon-mask.png')
- ).downloadAsync();
- Asset.fromModule(
- require('react-navigation/src/views/assets/back-icon.png')
- ).downloadAsync();
- }
- render() {
- const { navigation } = this.props;
- const scale = this.state.scrollY.interpolate({
- inputRange: [-450, 0, 100],
- outputRange: [2, 1, 0.8],
- extrapolate: 'clamp',
- });
- const translateY = this.state.scrollY.interpolate({
- inputRange: [-450, 0, 100],
- outputRange: [-150, 0, 40],
- });
- const opacity = this.state.scrollY.interpolate({
- inputRange: [0, 50],
- outputRange: [1, 0],
- extrapolate: 'clamp',
- });
- const underlayOpacity = this.state.scrollY.interpolate({
- inputRange: [0, 50],
- outputRange: [0, 1],
- extrapolate: 'clamp',
- });
- const backgroundScale = this.state.scrollY.interpolate({
- inputRange: [-450, 0],
- outputRange: [3, 1],
- extrapolate: 'clamp',
- });
- const backgroundTranslateY = this.state.scrollY.interpolate({
- inputRange: [-450, 0],
- outputRange: [0, 0],
- });
- return (
- <View style={{ flex: 1 }}>
- <Animated.ScrollView
- style={{ flex: 1 }}
- scrollEventThrottle={1}
- onScroll={Animated.event(
- [
- {
- nativeEvent: { contentOffset: { y: this.state.scrollY } },
- },
- ],
- { useNativeDriver: true }
- )}
- >
- <Animated.View
- style={[
- styles.backgroundUnderlay,
- {
- transform: [
- { scale: backgroundScale },
- { translateY: backgroundTranslateY },
- ],
- },
- ]}
- />
- <Animated.View
- style={{ opacity, transform: [{ scale }, { translateY }] }}
- >
- <SafeAreaView
- style={styles.bannerContainer}
- forceInset={{ top: 'always', bottom: 'never' }}
- >
- <View style={styles.banner}>
- <Image
- source={require('./assets/NavLogo.png')}
- style={styles.bannerImage}
- />
- <Text style={styles.bannerTitle}>
- React Navigation Examples
- </Text>
- </View>
- </SafeAreaView>
- </Animated.View>
- <SafeAreaView forceInset={{ bottom: 'always', horizontal: 'never' }}>
- <View style={{ backgroundColor: '#fff' }}>
- {Object.keys(ExampleRoutes).map((routeName: string) => (
- <TouchableOpacity
- key={routeName}
- onPress={() => {
- let route = ExampleRoutes[routeName];
- if (route.screen || route.path || route.params) {
- const { path, params, screen } = route;
- const { router } = screen;
- const action =
- path && router.getActionForPathAndParams(path, params);
- navigation.navigate(routeName, {}, action);
- } else {
- navigation.navigate(routeName);
- }
- }}
- >
- <SafeAreaView
- style={styles.itemContainer}
- forceInset={{ veritcal: 'never', bottom: 'never' }}
- >
- <View style={styles.item}>
- <Text style={styles.title}>
- {ExampleInfo[routeName].name}
- </Text>
- <Text style={styles.description}>
- {ExampleInfo[routeName].description}
- </Text>
- </View>
- </SafeAreaView>
- </TouchableOpacity>
- ))}
- </View>
- </SafeAreaView>
- </Animated.ScrollView>
- <StatusBar barStyle="light-content" />
- <Animated.View
- style={[styles.statusBarUnderlay, { opacity: underlayOpacity }]}
- />
- </View>
- );
- }
- }
- const AppNavigator = createStackNavigator(
- {
- ...ExampleRoutes,
- Index: {
- screen: MainScreen,
- },
- },
- {
- initialRouteName: 'Index',
- headerMode: 'none',
- /*
- * Use modal on iOS because the card mode comes from the right,
- * which conflicts with the drawer example gesture
- */
- mode: Platform.OS === 'ios' ? 'modal' : 'card',
- }
- );
- export default AppNavigator;
- const styles = StyleSheet.create({
- item: {
- paddingHorizontal: 16,
- paddingVertical: 12,
- },
- itemContainer: {
- backgroundColor: '#fff',
- borderBottomWidth: StyleSheet.hairlineWidth,
- borderBottomColor: '#ddd',
- },
- image: {
- width: 120,
- height: 120,
- alignSelf: 'center',
- marginBottom: 20,
- resizeMode: 'contain',
- },
- statusBarUnderlay: {
- backgroundColor: '#673ab7',
- position: 'absolute',
- top: 0,
- left: 0,
- right: 0,
- height: Constants.statusBarHeight,
- },
- title: {
- fontSize: 16,
- fontWeight: 'bold',
- color: '#444',
- },
- description: {
- fontSize: 13,
- color: '#999',
- },
- backgroundUnderlay: {
- backgroundColor: '#673ab7',
- position: 'absolute',
- top: -100,
- height: 300,
- left: 0,
- right: 0,
- },
- bannerContainer: {
- // backgroundColor: '#673ab7',
- alignItems: 'center',
- },
- banner: {
- flexDirection: 'row',
- alignItems: 'center',
- padding: 16,
- },
- bannerImage: {
- width: 36,
- height: 36,
- resizeMode: 'contain',
- tintColor: '#fff',
- margin: 8,
- },
- bannerTitle: {
- fontSize: 18,
- fontWeight: '200',
- color: '#fff',
- marginVertical: 8,
- marginRight: 5,
- },
- });
|