web前端开发

React Navigation5.X (Stack,Botto

2020-03-18  本文已影响0人  会飞的鱼儿_0012

React Navigation V5 的发布和之前版本写法上有些不同,这篇文章就讲Stack,BottomTab,Drawer使用和登录权限认证

v5移除了createSwitchNavigator登录权限认证会和之前有些变动

在新版React Navigation V5中使用的新的HOC模式,只需要在应用最外层包裹 NavigationContainer

import React from 'React'
import { NavigationContainer } from '@react-navigation/native';

export default function App() {
  return (
    <NavigationContainer>{/* Rest of your app code */}</NavigationContainer>
  );
}

文章涉及代码:github

开始使用React Navigation V5

createStackNavigator

· StackNavigator现在的写法类似数据结构的堆栈
默认情况下屏幕的跳转方式 ios 从右侧滑入,android 从底部划入,可以在ScreenOptions中设置屏幕的跳转方式 cardStyleInterpolator文档

  screenOptions={{
      cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS,
  }}>
import React from 'react';

import {NavigationContainer} from '@react-navigation/native';
import {createStackNavigator} from '@react-navigation/stack';
import {HomeScreen, DetailsScreen} from './Screen';

const Stack = createStackNavigator();

function StackScreen() {
  return (
    <Stack.Navigator 
      screenOptions={{
        cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS,
      }}>
      <Stack.Screen name="Home" component={HomeScreen} />
      <Stack.Screen name="Details" component={DetailsScreen} />
    </Stack.Navigator>
  );
}

export default function App() {
  return (
    <NavigationContainer>
      <StackScreen />
    </NavigationContainer>
  );
}

createDrawerNavigator

93rpr-zkv73.gif

点击按钮或从屏幕侧边划入显示抽屉界面

import React from 'react';
import {NavigationContainer} from '@react-navigation/native';
import {createDrawerNavigator} from '@react-navigation/drawer';

const Drawer = createDrawerNavigator();
function DrawerScreen() {
  return (
    <Drawer.Navigator>
      <Drawer.Screen name="Home" component={HomeScreen} />
      <Drawer.Screen name="Setting" component={SettingScreen} />
    </Drawer.Navigator>
  );
}

export default function App() {
  return (
    <NavigationContainer>
      <DrawerScreen/>
    </NavigationContainer>
  );
}

createBottomTabNavigator


屏幕底部TabBar

import React from 'react';
import {View} from 'react-native';
import {NavigationContainer} from '@react-navigation/native';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
const Tab = createBottomTabNavigator();
const TabBarIcon = (focused, color) => {
  return (
    <View
      style={{
        width: focused ? 24 : 18,
        height: focused ? 24 : 18,
        backgroundColor: color,
      }}
    />
  );
};
function TabScreen() {
  return (
    <Tab.Navigator
      tabBarOptions={{activeTintColor: '#FD7328', inactiveTintColor: '#999'}}
      screenOptions={{
        tabBarIcon: ({focused, color}) => {
          return TabBarIcon(focused, color);
        },
      }}>
      <Tab.Screen
        name="Home"
        component={HomeScreen}
        options={{title: '首页'}}
      />
      <Tab.Screen
        name="Mine"
        component={MineScreen}
        options={{title: '我的'}}
      />
    </Tab.Navigator>
  );
}

export default function App() {
  return (
    <NavigationContainer>
      <TabScreen />
    </NavigationContainer>
  );
}

Stack,Drawer,BottomTab结合使用

import React from 'react';
import {View} from 'react-native';
import {NavigationContainer} from '@react-navigation/native';
import {
  createStackNavigator,
  CardStyleInterpolators,
} from '@react-navigation/stack';
import {createDrawerNavigator} from '@react-navigation/drawer';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import {HomeScreen, DetailsScreen, SettingScreen, MineScreen} from './Screen';

const Stack = createStackNavigator();

function StackScreen() {
  return (
    <Stack.Navigator
      screenOptions={{
        cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS,
      }}>
      <Stack.Screen name="Drawer" component={DrawerScreen} />
      <Stack.Screen name="Details" component={DetailsScreen} />
    </Stack.Navigator>
  );
}

const Drawer = createDrawerNavigator();

function DrawerScreen() {
  return (
    <Drawer.Navigator>
      <Drawer.Screen name="Tab" component={TabScreen} />
      <Drawer.Screen name="Setting" component={SettingScreen} />
    </Drawer.Navigator>
  );
}

const Tab = createBottomTabNavigator();

const TabBarIcon = (focused, color) => {
  return (
    <View
      style={{
        width: focused ? 24 : 18,
        height: focused ? 24 : 18,
        backgroundColor: color,
      }}
    />
  );
};
function TabScreen() {
  return (
    <Tab.Navigator
      tabBarOptions={{activeTintColor: '#FD7328', inactiveTintColor: '#999'}}
      screenOptions={{
        tabBarIcon: ({focused, color}) => {
          return TabBarIcon(focused, color);
        },
      }}>
      <Tab.Screen
        name="Home"
        component={HomeScreen}
        options={{title: '首页'}}
      />
      <Tab.Screen
        name="Mine"
        component={MineScreen}
        options={{title: '我的'}}
      />
    </Tab.Navigator>
  );
}

export default function App() {
  return (
    <NavigationContainer>
      <StackScreen />
    </NavigationContainer>
  );
}

登录权限认证

v5版本之前可以使用createSwitchNavigator做登录身份认证,在V5版本移除了这个方法,可以使用V5新特性,根据状态定义和更改导航器的内容

本次使用react Context进行管理,也可根据项目需要使用reduxmobx

1.创建context

import React from 'react';

export const AuthContext = React.createContext();

2.屏幕导航

// screen
export function SettingScreen() {
  const {signOut} = React.useContext(AuthContext);
  return (
    <BaseCenterView>
      <Text>设置</Text>
      <Button
        title="退出登录"
        onPress={() => {
          signOut();
        }}
      />
    </BaseCenterView>
  );
}
export function SignInScreen() {
  const {signIn} = React.useContext(AuthContext);
  return (
    <BaseCenterView>
      <Text>登录页面</Text>
      <Button
        title="登录"
        onPress={() => {
          signIn();
        }}
      />
    </BaseCenterView>
  );
}
export function SplashScreen() {
  return (
    <BaseCenterView>
      <Text>loading...</Text>
    </BaseCenterView>
  );
}
// Auth屏幕堆栈
const AuthStack = createStackNavigator();
const AuthStackScreen = () => (
  <AuthStack.Navigator headerMode="none">
    <AuthStack.Screen name="SignIn" component={SignInScreen} />
  </AuthStack.Navigator>
);
// APP堆栈
const Drawer = createDrawerNavigator();
function DrawerScreen() {
  return (
    <Drawer.Navigator>
      <Drawer.Screen name="Tab" component={TabScreen} />
      <Drawer.Screen name="Setting" component={SettingScreen} />
    </Drawer.Navigator>
  );
}

const Tab = createBottomTabNavigator();
const TabBarIcon = (focused, color) => {
  return (
    <View
      style={{
        width: focused ? 24 : 18,
        height: focused ? 24 : 18,
        backgroundColor: color,
      }}
    />
  );
};

function TabScreen() {
  return (
    <Tab.Navigator
      tabBarOptions={{activeTintColor: '#FD7328', inactiveTintColor: '#999'}}
      screenOptions={{
        tabBarIcon: ({focused, color}) => {
          return TabBarIcon(focused, color);
        },
      }}>
      <Tab.Screen
        name="Home"
        component={HomeScreen}
        options={{title: '首页'}}
      />
      <Tab.Screen
        name="Mine"
        component={MineScreen}
        options={{title: '我的'}}
      />
    </Tab.Navigator>
  );
}

const MainStack = createStackNavigator();
function MainStackScreen() {
  return (
    <MainStack.Navigator
      screenOptions={{
        cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS,
      }}>
      {/* <MainStack.Screen name="Drawer" component={DrawerScreen} /> */}
      <MainStack.Screen name="Home" component={HomeScreen} />
      <MainStack.Screen name="Details" component={DetailsScreen} />
    </MainStack.Navigator>
  );
}
// Root堆栈
const RootStack = createStackNavigator();
const RootStackScreen = ({userToken = false}) => (
  <RootStack.Navigator headerMode="none">
    {userToken ? (
      <RootStack.Screen
        name="App"
        component={MainStackScreen}
        options={{
          animationEnabled: false,
        }}
      />
    ) : (
      <RootStack.Screen
        name="Auth"
        component={AuthStackScreen}
        options={{
          animationEnabled: false,
        }}
      />
    )}
  </RootStack.Navigator>
);
// 主路由
export default () => {
  const [isLoading, setIsLoading] = React.useState(true);
  const [userToken, setUserToken] = React.useState(null);

  const authContext = React.useMemo(() => {
    return {
      signIn: () => {
        setIsLoading(false);
        setUserToken('asdf');
      },
      signUp: () => {
        setIsLoading(false);
        setUserToken('asdf');
      },
      signOut: () => {
        setIsLoading(false);
        setUserToken(null);
      },
    };
  }, []);

  React.useEffect(() => {
    setTimeout(() => {
      setIsLoading(false);
    }, 1000);
  }, []);
  if (isLoading) {
    return <SplashScreen />;
  }
  return (
    <AuthContext.Provider value={authContext}>
      <NavigationContainer>
        <RootStackScreen userToken={userToken} />
      </NavigationContainer>
    </AuthContext.Provider>
  );
};

结束

文章涉及代码:github

上一篇下一篇

猜你喜欢

热点阅读