知识点GET
- React Navigation 5.x安装
- react-native-vector-icons安装与配置
- React Navigation传参和跳转
- 夜间模式的支持演示
视频教程
详细了解可以看我录的视频:
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
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';
export function useThemeColor(props, colorName) {
const theme = useColorScheme();
const colorFromProps = props[theme];
if (colorFromProps) {
return colorFromProps;
} else {
return Colors[theme][colorName];
}
}
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
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
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
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
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
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
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