(2020)React Native入门-React Navigation 5.x+react-native-vector-icons+夜间模式

知识点GET

  1. React Navigation 5.x安装
  2. react-native-vector-icons安装与配置
  3. React Navigation传参和跳转
  4. 夜间模式的支持演示

视频教程

详细了解可以看我录的视频:

https://www.bilibili.com/video/BV1VV411m74Z/

实现效果

普通模式

夜间模式

新建RN项目

npx react-native init NavigationDemo

换国内清华大学的提高速度(非必须)

ios/Podfile文件头部增加下面

source 'https://mirrors.tuna.tsinghua.edu.cn/git/CocoaPods/Specs.git'

 文档

https://reactnavigation.org/

npm install

核心模块

npm install @react-navigation/native

相关依赖 

npm install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view

StackNavigator 

npm install @react-navigation/stack

BottomTabNavigator 

npm install @react-navigation/bottom-tabs

安装react-native-vector-icons组件

这个组件中有很多有用的图标,先安装一下,后面会用到。

npm install react-native-vector-icons --save

IOS配置

修改/NavigationDemo/ios/NavigationDemo/Info.plist配置文件,增加一些配置:

<key>UIAppFonts</key>
  <array>
    <string>AntDesign.ttf</string>
    <string>Entypo.ttf</string>
    <string>EvilIcons.ttf</string>
    <string>Feather.ttf</string>
    <string>FontAwesome.ttf</string>
    <string>FontAwesome5_Brands.ttf</string>
    <string>FontAwesome5_Regular.ttf</string>
    <string>FontAwesome5_Solid.ttf</string>
    <string>Foundation.ttf</string>
    <string>Ionicons.ttf</string>
    <string>MaterialIcons.ttf</string>
    <string>MaterialCommunityIcons.ttf</string>
    <string>SimpleLineIcons.ttf</string>
    <string>Octicons.ttf</string>
    <string>Zocial.ttf</string>
    <string>Fontisto.ttf</string>
  </array>

android配置

NavigationDemo/android/app/build.gradle

修改这个配置文件,增加以下配置

project.ext.vectoricons = [
        iconFontNames: ['AntDesign.ttf',
                        'Entypo.ttf',
                        'EvilIcons.ttf',
                        'Feather.ttf',
                        'FontAwesome.ttf',
                        'FontAwesome5_Brands.ttf',
                        'FontAwesome5_Regular.ttf',
                        'FontAwesome5_Solid.ttf',
                        'Foundation.ttf',
                        'Ionicons.ttf',
                        'MaterialIcons.ttf',
                        'MaterialCommunityIcons.ttf',
                        'SimpleLineIcons.ttf',
                        'Octicons.ttf',
                        'Zocial.ttf',
                        'Fontisto.ttf'] // Name of the font files you want to copy
]

apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"

pod install

 npx pod-install

代码实现

根部导航器

js/navigation/index.js

/* eslint-disable prettier/prettier */
import * as React from 'react';
import {createStackNavigator} from '@react-navigation/stack';
import TabNav from './TabNav';
import LoginScreen from '../screen/LoginScreen';
import DetailScreen from '../screen/DetailScreen';

const Stack = createStackNavigator();

function App() {
    return (
        <Stack.Navigator initialRouteName="LoginPage">
            <Stack.Screen
                name="LoginScreen"
                component={LoginScreen}
                options={{title: '登录', headerShown: false}}
            />
            <Stack.Screen
                name="TabNav"
                component={TabNav}
                options={{title: '首页', headerShown: false}}
            />

            <Stack.Screen
                name="DetailScreen"
                component={DetailScreen}
                options={({route, navigation}) => ({
                    title: route.params.screenName,
                })}
            />
        </Stack.Navigator>
    );
}

export default App;

底部TAB导航配置

js/navigation/TabNav.js

import * as React from 'react';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import {createStackNavigator} from '@react-navigation/stack';
import SchoolScreen from '../screen/SchoolScreen';
import HomeScreen from '../screen/HomeScreen';
import MessageScreen from '../screen/MessageScreen';
import SettingsScreen from '../screen/SettingsScreen';
import AntDesign from 'react-native-vector-icons/AntDesign';

export default function Navigation({colorScheme}) {
  return (
    <Tab.Navigator
      screenOptions={({route}) => ({
        tabBarIcon: ({focused, color, size}) => {
          if (route.name === 'index') {
            return <AntDesign name="home" size={size} color={color} />;
          } else if (route.name === 'school') {
            return <AntDesign name="cloudo" size={size} color={color} />;
          } else if (route.name === 'message') {
            return <AntDesign name="mail" size={size} color={color} />;
          } else if (route.name === 'setting') {
            return <AntDesign name="setting" size={size} color={color} />;
          }
        },
      })}>
      <Tab.Screen
        name="index"
        component={HomeScreen}
        options={{title: '首页', headerMode: 'none'}}
      />
      <Tab.Screen
        name="school"
        component={SchoolNavigator}
        options={{title: '校园'}}
      />
      <Tab.Screen
        name="message"
        component={MessageNavigator}
        options={{title: '消息'}}
      />

      <Tab.Screen
        name="setting"
        component={SettingsScreenNavigator}
        options={{title: '设置'}}
      />
    </Tab.Navigator>
  );
}
const Tab = createBottomTabNavigator();
const TabStack = createStackNavigator();

function SchoolNavigator() {
  return (
    <TabStack.Navigator>
      <TabStack.Screen
        name="School"
        component={SchoolScreen}
        options={{
          headerTitle: '校园',
          headerLeft: null,
          headerTitleAlign: 'center',
        }}
      />
    </TabStack.Navigator>
  );
}

function MessageNavigator() {
  return (
    <TabStack.Navigator>
      <TabStack.Screen
        name="School"
        component={MessageScreen}
        options={{
          headerTitle: '消息',
          headerLeft: null,
          headerTitleAlign: 'center',
        }}
      />
    </TabStack.Navigator>
  );
}

function SettingsScreenNavigator() {
  return (
    <TabStack.Navigator>
      <TabStack.Screen
        name="School"
        component={SettingsScreen}
        options={{
          headerTitle: '我是设置标题',
          headerLeft: null,
          headerTitleAlign: 'center',
        }}
      />
    </TabStack.Navigator>
  );
}

暗黑主题组件封装

/js/components/Themed.js

import * as React from 'react';
import {
  Text as DefaultText,
  View as DefaultView,
  useColorScheme,
} from 'react-native';

import Colors from '../constants/Colors';

/**
 * 自定义hook
 * @param props
 * @param colorName
 */
export function useThemeColor(props, colorName) {
  const theme = useColorScheme();
  const colorFromProps = props[theme];

  if (colorFromProps) {
    return colorFromProps;
  } else {
    return Colors[theme][colorName];
  }
}

/**
 * 自定义Text组件,使其自动适配暗黑模式
 * @param props 参数
 * @returns {*}
 * @constructor
 */
export function Text(props) {
  const {style, lightColor, darkColor, ...otherProps} = props;
  //使用hook获取当前的主题颜色
  const color = useThemeColor({light: lightColor, dark: darkColor}, 'text');
  //设置前景色
  return <DefaultText style={[{color}, style]} {...otherProps} />;
}

export function View(props) {
  const {style, lightColor, darkColor, ...otherProps} = props;
  const backgroundColor = useThemeColor(
    {light: lightColor, dark: darkColor},
    'background',
  );

  //设置背景色
  return <DefaultView style={[{backgroundColor}, style]} {...otherProps} />;
}

主题颜色配置常量

js/constants/Colors.js

const tintColorLight = '#2f95dc';
const tintColorDark = '#fff';

export default {
  light: {
    text: '#000',
    background: '#fff',
    tint: tintColorLight,
    tabIconDefault: '#ccc',
    tabIconSelected: tintColorLight,
  },
  dark: {
    text: '#fff',
    background: '#000',
    tint: tintColorDark,
    tabIconDefault: '#ccc',
    tabIconSelected: tintColorDark,
  },
};

登录页代码

js/screen/LoginScreen.js

/* eslint-disable prettier/prettier */
import React from 'react';
import {Button} from 'react-native';
import {
    Text,
    View,
} from '../components/Themed';

const LoginScreen = ({navigation})=> {
    return (
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
            <Text>登录页面</Text>
            <Button title={"登录"} onPress={()=>{
                navigation.navigate('TabNav');
            }} />
        </View>
    );
};

export default LoginScreen;

首页

js/screen/HomeScreen.js

/* eslint-disable prettier/prettier */
import React from 'react';
import {
    Text,
    View,
} from '../components/Themed';

const HomeScreen = ()=> {
    return (
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
            <Text>首页</Text>
        </View>
    );
};

export default HomeScreen;

消息

js/screen/MessageScreen.js

/* eslint-disable prettier/prettier */
import React from 'react';
import {
    Text,
    View,
} from '../components/Themed';

const MessageScreen = ()=> {
    return (
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
            <Text>消息</Text>
        </View>
    );
};

export default MessageScreen;

校园

js/screen/SchoolScreen.js

/* eslint-disable prettier/prettier */
import React from 'react';
import {
    Text,
    View,
} from '../components/Themed';

const SchoolScreen = ()=> {
    return (
        <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
            <Text>校园</Text>
        </View>
    );
};

export default SchoolScreen;

设置

js/screen/SettingsScreen.js

/* eslint-disable prettier/prettier */
import React from 'react';
import {
    Text,
    View,
} from '../components/Themed';
import {Button} from 'react-native';

const SettingsScreen = ({navigation})=> {
  return (
      <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Text>设置</Text>
          <Button title={"回到登录页"} onPress={()=>{
              navigation.navigate('LoginScreen');
          }} />

          <Button title={"详情页面传参测试"} onPress={()=>{
              navigation.navigate('DetailScreen',{
                  screenName: '自定义标题',
                  url: 'http://www.baidu.com',
              });
          }} />
      </View>
  );
};

export default SettingsScreen;

详情页面

js/screen/DetailScreen.js

/* eslint-disable prettier/prettier */
import React from 'react';
import {
    Text,
    View,
} from '../components/Themed';

const DetailScreen = ({route})=> {
  return (
      <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Text>详情页面</Text>
        <Text>标题是:{route.params.screenName}</Text>
        <Text>参数Url是:{route.params.url}</Text>
      </View>
  );
};

export default DetailScreen;

App.js

App.js

import React from 'react';
import {
  StyleSheet,
  SafeAreaView,
  StatusBar,
  useColorScheme,
} from 'react-native';
import Navigation from './js/navigation';
import {
  DarkTheme,
  DefaultTheme,
  NavigationContainer,
} from '@react-navigation/native';

const App = () => {
  const colorScheme = useColorScheme();
  return (
    <NavigationContainer
      theme={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
      <Navigation />
      <StatusBar />
    </NavigationContainer>
  );
};

export default App;

至此代码结束。

源码分享:

https://download.csdn.net/download/lxyoucan/12819575

猜你喜欢

转载自blog.csdn.net/lxyoucan/article/details/108427400