关于ReactNative导航5.x的学习分享,话不多说,直接上菜
研究这个ReactNative导航我研究了三天,才整明白。有的博客写的是4.x版本,有的博客写的是5.x版本。初次接触的朋友,可能你根本不知道有这么多版本,当你写完报错4.x版本和5.x版本不能混合使用的时候,你或许才明白有很多个版本,然后你就大骂一句*****,网上多4.x版本的博客,所以我才打算记录一下这个5.x版本的内容。
项目目录:就只是在项目根目录下面创建了src文件夹,src下面有个Pages文件夹,Pages文件夹下面有那五个js文件(除App.js文件外的五个)。
需要安装得依赖
一、
1.依赖安装(下载报错就重新下载)
npm install @react-navigation/native
2.navigation的运行会依赖于如下依赖项,安装这些库
npm install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view
3.链接2中的库(0.60版本以上的跳过此步骤)React Native 0.60及更高版本开始,会自动链接,如果你版本是0.60及以上,这一步就可以跳过;而React Native 0.59以及更低版本则需要手动链接,安装react-native link。
react-native link react-native-reanimated
react-native link react-native-gesture-handler
react-native link react-native-screens
react-native link react-native-safe-area-context
4.在入口文件(index.js或App.js)的头部引入如下依赖
import ‘react-native-gesture-handler’;
5.安装navigator库:有三种导航模式可以选,分别是StackNavigator栈导航、TabNavigator标签导航、DrawerNavigator抽屉导航。
//StackNavigator
npm install @react-navigation/stack
//TabNavigator
npm install @react-navigation/bottom-tabs
//DrawerNavigator
npm install @react-navigation/drawer
App.js
import React from 'react';
import {
SafeAreaView,
StyleSheet,
ScrollView,
View,
Text,
StatusBar,
Button,
Image,
Linking
} from 'react-native';
import {Header, LearnMoreLinks, Colors, DebugInstructions, ReloadInstructions,} from 'react-native/Libraries/NewAppScreen';
import {NavigationContainer} from '@react-navigation/native'
import {createStackNavigator} from '@react-navigation/stack'
import { from } from 'rxjs';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { createDrawerNavigator, DrawerContentScrollView, DrawerItemList, DrawerItem} from '@react-navigation/drawer'
import HomeIconActive from './images/icon_home_active.png'
import HomeIconNormal from './images/icon_home_normal.png'
import WorkIconActive from './images/icon_work_active.png'
import WorkIconNormal from './images/icon_work_normal.png'
import HomeScreen from './src/Pages/HomeScreen'
import SettingsScreen from './src/Pages/SettingsScreen';
import DetailScreen from './src/Pages/DetailScreen';
import LoginScreen from './src/Pages/LoginScreen';
import newPageScreen from './src/Pages/newPage';
/**====================BottomTabNavigator部分================================**/
//设置BottomTabNavigator的icon
//badgeCount是icon上面的小角标
function IconWithBadge({ icon, badgeCount, size }) {
return (
<View style={{ width: 24, height: 24, margin: 5 }}>
<Image source={icon} style={{
width: size,
height: size
}} />
{badgeCount > 0 && (
<View
style={{
// On React Native < 0.57 overflow outside of parent will not work on Android, see https://git.io/fhLJ8
position: 'absolute',
right: -6,
top: -3,
backgroundColor: 'red',
borderRadius: 6,
width: 12,
height: 12,
justifyContent: 'center',
alignItems: 'center',
}}
>
<Text style={{ color: 'white', fontSize: 10, fontWeight: 'bold' }}>
{badgeCount}
</Text>
</View>
)}
</View>
);
}
function HomeIconWithBadge(props) {
// You should pass down the badgeCount in some other ways like React Context API, Redux, MobX or event emitters.
return <IconWithBadge {...props} badgeCount={3} />;
}
//设置BottomTabNavigator
const Tab = createBottomTabNavigator();
const TabScreen = () => {
return (
<Tab.Navigator
headerMode='none'
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
if (route.name === '首页') {
return (
<HomeIconWithBadge
icon={
focused
? HomeIconActive
: HomeIconNormal
}
size={size}
color={color}
/>
);
} else if (route.name === 'Settings') {
return (
<Image
source={focused ? WorkIconActive : WorkIconNormal}
style={{width: size, height: size}}
/>
);
}
},
})}
tabBarOptions={{
activeTintColor: 'tomato',
inactiveTintColor: 'gray',
}}
>
<Tab.Screen name="首页" component={HomeScreen} />{/*name这个代表这个bottomBar的名字*/}
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
)
}
/**====================RootStackNavigator部分================================**/
const RootStack = createStackNavigator();
const rootRouteScreen = () => {
return (
<RootStack.Navigator initialRouteName={'TabNav'}>
{/*把创建的BottomTabNavigator设置到根导航下面*/}
<RootStack.Screen name='TabNav' component={TabScreen} />
{/*这里设置去Detail页面的导航设置*/}
<RootStack.Screen name="Detail" component={DetailScreen} />
{/*这个name是和去页面(settings页面)的this.props.navigation.navigate里面的东西是一样的*/}
<RootStack.Screen name="newPage" component={newPageScreen} />
</RootStack.Navigator>
)
}
/**====================DrawerNavigator部分================================**/
/**创建DrawerNavigator**/
/**必须要有这个才能运行,不能只有App里面return的DrawerNavigator**/
const Drawer = createDrawerNavigator();
const DrawerStack = () => {
return(
<Drawer.Navigator >
{/*不清楚为什么这里面可以不写<Drawer.Screen name="Home" component={HomeScreen} />必须要在App里面return的DrawerNavigator里面写*/}
</Drawer.Navigator>
)
}
/**这个也是相当于DrawerNavigator的一项。并不清楚为什么要写在这里,不知道是不是因为导航层级关系的原因**/
/**或许是相对于下面的另外一种写法**/
const CustomDrawerContent = (props) => {
return(
<DrawerContentScrollView {...props}>
<DrawerItemList {...props}/>
<DrawerItem
label="Help"
onPress={() => props.navigation.navigate('Detail',{
itemId: 86,
otherParam: 'anything you want here',
})}
/>
</DrawerContentScrollView>
)
}
const App = () => {
return (
<NavigationContainer>
<Drawer.Navigator initialRouteName="Home"
drawerType='slide'
drawerContent={(props) => <CustomDrawerContent {...props} />}
>
{/*这里添加DrawerNavigator需要加的页面,不知道为什么不能在上面的函数里面添加*/}
<Drawer.Screen name='首页' component={rootRouteScreen} />
<Drawer.Screen name='设置' component={SettingsScreen} />
<Drawer.Screen name='登录' component={LoginScreen} />
</Drawer.Navigator>
</NavigationContainer>
);
}
const styles = StyleSheet.create({
scrollView: {
backgroundColor: Colors.lighter,
},
engine: {
position: 'absolute',
right: 0,
},
body: {
backgroundColor: Colors.white,
},
sectionContainer: {
marginTop: 32,
paddingHorizontal: 24,
},
sectionTitle: {
fontSize: 24,
fontWeight: '600',
color: Colors.black,
},
sectionDescription: {
marginTop: 8,
fontSize: 18,
fontWeight: '400',
color: Colors.dark,
},
highlight: {
fontWeight: '700',
},
footer: {
color: Colors.dark,
fontSize: 12,
fontWeight: '600',
padding: 4,
paddingRight: 12,
textAlign: 'right',
},
});
export default App;
DetailScreen.js
import React, {Component} from 'react';
import {View, Text, TouchableOpacity, StyleSheet,Button} from 'react-native';
export default class DetailScreen extends Component {
constructor(props) {
super(props);
}
render() {
const params = this.props.route.params;
return (
<View>
<View style={{padding:20,backgroundColor: 'green'}}>
<Text>DetailScreen</Text>
</View>
<View style={{ alignItems: 'center', justifyContent: 'center'}}>
<Text>DetailScreen:{params.itemId}{params.otherParam}</Text>
<View style={{margin:20,padding:20,backgroundColor: 'green'}}>
<Button title="Go to Home" onPress={() => this.props.navigation.navigate('Home')}/>
</View>
<View style={{margin:20,padding:20,backgroundColor: 'green'}}>
<Button title="Go back" onPress={() => this.props.navigation.goBack()}/>
</View>
<View style={{margin:20,padding:20,backgroundColor: 'green'}}>
<Button
title="Go back to first screen in stack"
onPress={() => this.props.navigation.popToTop()}
/>
</View>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
button: {
width: 250,
marginTop: 80,
marginLeft: 50,
minHeight: 46,
paddingHorizontal: 15,
paddingVertical: 6,
borderStyle: 'solid',
borderWidth: 1,
borderRadius: 8,
borderColor: '#ae9373',
backgroundColor: '#f5f5f5',
textAlign: 'center',
},
buttonText: {
color: '#ae9373',
fontSize: 20,
lineHeight: 30,
textAlign: 'center',
},
});
HomeScreen.js
import React, { Component } from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
export default class HomeScreen extends Component {
constructor(props) {
super(props);
}
render() {
console.log(this.props)
return (
<View>
<Text>HomeScreen</Text>
<TouchableOpacity style={styles.button} onPress={() => this.props.navigation.navigate('Detail',{itemId:86, otherParam:'anything you want here'})}>
<Text style={styles.buttonText}>Go to Detail Page</Text>
</TouchableOpacity>
</View>
)
}
}
const styles = StyleSheet.create({
button: {
width: 250,
marginTop: 80,
marginLeft: 50,
minHeight: 46,
paddingHorizontal: 15,
paddingVertical: 6,
borderStyle: 'solid',
borderWidth: 1,
borderRadius: 8,
borderColor: '#ae9373',
backgroundColor: '#f5f5f5',
textAlign: 'center'
},
buttonText: {
color: '#ae9373',
fontSize: 20,
lineHeight: 30,
textAlign: 'center'
},
})
SettingsScreen.js
import React, { Component } from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
export default class SettingsScreen extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View>
<Text>SettingScreen</Text>
<TouchableOpacity style={styles.button} onPress={() => this.props.navigation.navigate('Detail',{itemId:86, otherParam:'我是要给Detail的数据,来自setting'})}>
<Text style={styles.buttonText}>Go to Detail Page</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button} onPress={() => this.props.navigation.navigate('newPage')}>
<Text style={styles.buttonText}>Go to newPage Page</Text>
</TouchableOpacity>
</View>
)
}
}
const styles = StyleSheet.create({
button: {
width: 250,
marginTop: 80,
marginLeft: 50,
minHeight: 46,
paddingHorizontal: 15,
paddingVertical: 6,
borderStyle: 'solid',
borderWidth: 1,
borderRadius: 8,
borderColor: '#ae9373',
backgroundColor: '#f5f5f5',
textAlign: 'center'
},
buttonText: {
color: '#ae9373',
fontSize: 20,
lineHeight: 30,
textAlign: 'center'
},
})
LoginScreen.js
import React, { Component } from 'react';
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
export default class LoginScreen extends Component {
constructor(props) {
super(props);
}
render() {
return (
<View>
<Text>这是login页面</Text>
<TouchableOpacity style={styles.button} onPress={() => this.props.navigation.navigate('Home')}>
<Text style={styles.buttonText}>Go to Home Page</Text>
</TouchableOpacity>
</View>
)
}
}
const styles = StyleSheet.create({
button: {
width: 250,
marginTop: 80,
marginLeft: 50,
minHeight: 46,
paddingHorizontal: 15,
paddingVertical: 6,
borderStyle: 'solid',
borderWidth: 1,
borderRadius: 8,
borderColor: '#ae9373',
backgroundColor: '#f5f5f5',
textAlign: 'center'
},
buttonText: {
color: '#ae9373',
fontSize: 20,
lineHeight: 30,
textAlign: 'center'
},
})
newPageScreen.js
import React, { Component } from 'react';
import { View, Text, TouchableOpacity, StyleSheet,ScrollView,ActivityIndicator,Button,Image } from 'react-native';
export default class newPageScreen extends Component {
constructor(props) {
super(props);
this.State={
data:''
}
}
getData=()=>{
console.warn(123)
fetch('数据地址', ).then(
res=>res.json()
).then(
res=>{
console.log(res)
console.warn(res)
// this.setState({
// data:res.item
// })
}
)
}
render() {
return (
<View style={styles.newPage}>
<Text>newPage页面</Text>
<View>
<ScrollView>
<Text>123</Text>
{/*{this.state.data.map(item=>{*/}
{/* return <Text>item.name</Text>*/}
{/*})}*/}
<ActivityIndicator size="large" color="red"/>
<Text>456</Text>
<Button
title="山竹"
onPress={() => this.getData()}
/>
<Image
source={{
uri:
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1593165329657&di=2cb808fe5fd9001d8a19f7661918b751&imgtype=0&src=http%3A%2F%2Fwww.fangshengjt.com%2Fimages%2F201709%2Fsource_img%2F34_P_1504918512385.jpg',
}}
style={{width: 300, height: 300}}
/>
<Image
source={{
uri:
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1593165329657&di=2cb808fe5fd9001d8a19f7661918b751&imgtype=0&src=http%3A%2F%2Fwww.fangshengjt.com%2Fimages%2F201709%2Fsource_img%2F34_P_1504918512385.jpg',
}}
style={{width: 300, height: 300}}
/>
<Image
source={{
uri:
'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1593165329657&di=2cb808fe5fd9001d8a19f7661918b751&imgtype=0&src=http%3A%2F%2Fwww.fangshengjt.com%2Fimages%2F201709%2Fsource_img%2F34_P_1504918512385.jpg',
}}
style={{width: 300, height: 300}}
/>
<Image
style={styles.tinyLogo}
source={{
uri: 'https://reactnative.dev/img/tiny_logo.png',
}}
/>
</ScrollView>
</View>
</View>
)
}
}
const styles = StyleSheet.create({
newPage:{
width:500,
borderStyle: 'solid',
borderWidth: 1,
borderColor: '#ae9373',
backgroundColor: '#55ffe1',
textAlign: 'center'
}
})