React Navigation 官网地址:https://reactnavigation.org/docs/en/api-reference.html
在React Navigation2.0版本中有以下组件:
- createStackNavigator
- createSwitchNavigator
- createDrawerNavigator
- createTabNavigator
- createBottomTabNavigator
- createMaterialBottomTabNavigator
- createMaterialTopTabNavigator
下面逐一列举我在开发中遇到的问题:
一、嵌套问题
官网中有关这一问题的解决方案https://reactnavigation.org/docs/en/common-mistakes.html
我项目中的跳转关系:
闪屏页跳转到主页,闪屏页不保存在栈中,主页是四个Tab,首页中上面是城市可以跳转到下一个界面,里面又包括两个Tab
闪屏页.png
主页.png
首先,由闪屏页跳转到主页,因为闪屏页跳转完成后,不再返回该界面,所以采用createSwitchNavigator
/*
* @Author: sunmingmao
* @Date: 2018-05-15 11:45:10
* @Last Modified by: sunmingmao
* @Last Modified time: 2018-05-15 14:36:55
*/
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Button,
View
} from 'react-native';
import {createSwitchNavigator} from 'react-navigation';
import MainStackNavigator from "./src/MainStackNavigator";
class AppScreen extends React.Component {
render() {
return (
<View style={styles.container}>
<Button title="skip" onPress={()=>{this.props.navigation.navigate('MainStackNavigator')}}/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
});
export default App = createSwitchNavigator({
AppScreen:AppScreen,
MainStackNavigator:MainStackNavigator
});
主页,我们先思考一个问题,
首页,电影,书店,我的,这四部分应该写在一个createBottomTabNavigator中,但是其中 城市选择详情页,正在热映中的Skip跳转到的界面,这两个界面应该注册在哪里呢?--- 包含四个Tab的createBottomTabNavigator和各详情界面都应该注册在同一个createStackNavigator中,他们是平级的
先看一下 首页,电影,书店,我的,四个Tab的写法
/*
* @Author: sunmingmao
* @Date: 2018-05-15 14:15:45
* @Last Modified by: sunmingmao
* @Last Modified time: 2018-05-15 16:18:48
*/
import React, { Component } from 'react';
import { Image } from 'react-native';
import { createBottomTabNavigator } from 'react-navigation';
import MovieScreen from "./movie/MovieScreen";
import HomeScreen from "./home/HomeScreen";
import MineScreen from "./mine/MineScreen";
import LibraryScreen from "./library/LibraryScreen";
const MainTabNavigator = createBottomTabNavigator({
HomeScreen: {
screen: HomeScreen,
navigationOptions: {
title: "首页",
tabBarIcon: ({ focused, tintColor }) => {
icon = focused ? require("./image/home_focus.png") : require("./image/home_unfocus.png");
return (<Image source={icon} style={{ width: 20, height: 20 }} />);
}
}
},
MovieScreen: {
screen: MovieScreen,
navigationOptions: {
title: "电影",
tabBarIcon: ({ focused, tintColor }) => {
icon = focused ? require("./image/movie_focus.png") : require("./image/movie_unfocus.png");
return (<Image source={icon} style={{ width: 20, height: 20 }} />);
}
}
},
LibraryScreen: {
screen: LibraryScreen,
navigationOptions: {
title: "书店",
tabBarIcon: ({ focused, tintColor }) => {
icon = focused ? require("./image/library_focus.png") : require("./image/library_unfocus.png");
return (<Image source={icon} style={{ width: 20, height: 20 }} />);
}
}
},
MineScreen: {
screen: MineScreen,
navigationOptions: {
title: "我的",
tabBarIcon: ({ focused, tintColor }) => {
icon = focused ? require("./image/mine_focus.png") : require("./image/mine_unfocus.png");
return (<Image source={icon} style={{ width: 20, height: 20 }} />);
}
}
}
}, {
initialRouteName: 'HomeScreen',
tabBarOptions: {
activeTintColor: "#515151",
inactiveTintColor: "#8a8a8a"
}
});
export default MainTabNavigator;
再看一下 如何把城市详情和电影详情页注册进来
/*
* @Author: sunmingmao
* @Date: 2018-05-15 14:10:00
* @Last Modified by: sunmingmao
* @Last Modified time: 2018-05-15 14:52:00
*/
import React, { Component } from 'react';
import { createStackNavigator } from 'react-navigation';
import MainTabNavigator from "./MainTabNavigator";
import MovieDetails from "./movie/MovieDetails";
import HomeHottingDetails from "./home/HomeHottingDetalis";
import City from "./home/City";
const MainStackNavigator = createStackNavigator({
MainTabNavigator: {
screen: MainTabNavigator,
navigationOptions:{
header:null
}
},
MovieDetails: {
screen: MovieDetails
},
HomeHottingDetails:{
screen:HomeHottingDetails
},
City:{
screen:City
}
});
export default MainStackNavigator;
在首页中,我又放入了一个createTabNavigator,分别展示 正在热映 即将热映,此时的createTabNavigator是作为组件引入到HomeScreen.js中的。
这种方式需要注意一些问题,先看代码
/*
* @Author: sunmingmao
* @Date: 2018-05-15 14:18:11
* @Last Modified by: sunmingmao
* @Last Modified time: 2018-05-15 16:24:14
*/
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet
} from 'react-native';
import {createTabNavigator} from 'react-navigation';
import HomeHotingScreen from "./HomeHotingTab";
import HomeUpingScreen from "./HomeUpingTab";
const HomeTabNavigator = createTabNavigator({
HomeHotingScreen:{
screen:HomeHotingScreen,
navigationOptions:{
title:"正在热映"
}
},
HomeUpingScreen:{
screen:HomeUpingScreen,
navigationOptions:{
title:"即将上映"
}
}
},{
tabBarPosition:'top',
tabBarOptions:{
activeTintColor:"#515151",
inactiveTintColor:"#8a8a8a",
style:{
backgroundColor:"#fff"
},
labelStyle:{
},
indicatorStyle:{
backgroundColor:"#515151"
}
}
});
export default HomeTabNavigator;
/*
* @Author: sunmingmao
* @Date: 2018-05-15 15:04:57
* @Last Modified by: sunmingmao
* @Last Modified time: 2018-05-15 15:42:02
*/
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet
} from 'react-native';
import HomeTabNavigator from "./HomeTabNavigator";
export default class HomeScreen extends React.Component {
static router = HomeTabNavigator.router;
constructor(props) {
super(props);
this.state = {
city: "济南"
}
}
render() {
return (
<View style={styles.container}>
<View style={styles.topContainer}>
<Text style={styles.cityText}
onPress={() => {
this.props.navigation.navigate('City', {
city: this.state.city,
callBack: (params) => {
this.setState({
city: params
});
}
});
}}>{this.state.city}</Text>
</View>
<HomeTabNavigator navigation={this.props.navigation} />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
topContainer: {
flexDirection: 'row',
height: 48,
alignItems: 'center',
backgroundColor: '#fff',
},
cityText: {
fontSize: 14,
padding: 12,
}
});
其中 需要注意
static router = HomeTabNavigator.router;
<HomeTabNavigator navigation={this.props.navigation} />
这是作为组件嵌套的一个写法
二、传值 与 回传值 问题
navigate();方法的第二个参数,就是要传递的值,
this.props.navigation.navigate('City', {
city: this.state.city,
callBack: (params) => {
this.setState({
city: params
});
}
});
接受值 与 回传值的方法 如下:
/*
* @Author: sunmingmao
* @Date: 2018-05-15 15:25:21
* @Last Modified by: sunmingmao
* @Last Modified time: 2018-05-15 15:43:05
*/
import React, { Component } from 'react';
import {
View,
Text,
StyleSheet
} from 'react-native'
export default class CityScreen extends React.Component {
render() {
const {params} = this.props.navigation.state;
return (
<View style={styles.container}>
<Text>当前所在城市:{params.city}</Text>
<Text style={styles.cityText} onPress={()=>{params.callBack("北京");this.props.navigation.goBack();}}>北京</Text>
<Text style={styles.cityText} onPress={()=>{params.callBack("上海");this.props.navigation.goBack();}}>上海</Text>
<Text style={styles.cityText} onPress={()=>{params.callBack("深圳");this.props.navigation.goBack();}}>深圳</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
cityText:{
fontSize:14,
margin:10
}
});
网友评论