React 学习笔记
一、Navigator
- Navigator还有一个兄弟组件NavigatorIOS,但是NavigatorIOS只能在IOS中使用,在Android中不能使用,而Navigator既可以在IOS中使用,也可以在Android中使用。
1、Navigator属性
initialRoute(Object) –用来设置初始显示页面,可以传递navigator参数
例如:initialRoute={{id: 'firstPage', title : "FirstPage"}}
renderScene(Function(route, navigator)) –用来渲染显示的页面,可以根据navigator传递的参数进行筛选判断
例如: “`renderScene={this.renderSceneFun} renderSceneFun(route, navigator) { switch (route.id) { case 'first': return <FirstPage navigator={navigator} title="FirstPage"/>; case 'second': return (<SecondPage navigator={navigator} title="SecondPage" data={route.data}/>); } }
“`
其中renderScene方法中的传入的参数route就是initialRoute,而另外一个参数navigator就是当前上下文的页面导航控制器,通过对navigator进行push或pop操作来进行载入新视图或者后退。
navigator进行push的时候传入参数与initialRoute格式一样(实际上,在页面初始化的时候,react-native就会调用一次renderScene方法,并且将initialRoute作为renderScene的第一个参数(route)传入,同时新建一个navigator导航对象到内存中)翻看Navigator的源码可以看到,在Navigator的state中存在一个数组变量routeState,通过对该变量进行增加和删除元素进而实现了路由的切换。代码截图如下:
configureScene(Function(route, navigator)) –用来设置场景切换时的动作
传入参数与renderScene一样
返回类型可选:
- Navigator.SceneConfigs.PushFromRight (默认)
- Navigator.SceneConfigs.FloatFromRight
- Navigator.SceneConfigs.FloatFromLeft
- Navigator.SceneConfigs.FloatFromBottom
- Navigator.SceneConfigs.FloatFromBottomAndroid
- Navigator.SceneConfigs.FadeAndroid
- Navigator.SceneConfigs.HorizontalSwipeJump
- Navigator.SceneConfigs.HorizontalSwipeJumpFromRight
- Navigator.SceneConfigs.VerticalUpSwipeJump
- Navigator.SceneConfigs.VerticalDownSwipeJump
各参数的含义基本上从名字上就可以看出
navigationBar–用来定义一个在场景切换的时候保持的导航栏
navigationBar={ <Navigator.NavigationBar routeMapper={NavigationBarRouteMapper}/>}
其中NavigationBarRouteMapper为导航栏映射对象,含有LeftButton,RightButton,Title属性方法,方法均为在导航栏上面显示的对象,方法参数为:route, navigator, index, navigationState,前两个与renderScene和configureScene一样。
- index用来标记当前为从初始状态开始的第几个页面,初始状态时为0
- navigationState是当前Navigator对象的state属性(上面介绍Navigator流程时提到的state)可以供过该属性获取到当前Navigator对象的视图栈(routeState),然后可以从中获取之前视图的route属性(每次加载视图时push进去的)
/** * Created by jliu10 on 2017/2/20. */ 'use strict'; import React, {Component} from "react"; import { StyleSheet, Text, View, Navigator, TouchableOpacity } from "react-native"; class FirstPage extends Component { // 填出提示框 handleOnRightClick() { alert("Click RightButton!"); } /** * 跳转页面至SecondPage * @param type 动画类型 */ jumpPage(type = 'Normal') { this.props.navigator.push({ id: "secondPage", title: "SecondPage", rightBtnClick: this.handleOnRightClick, rightText: 'Button', type: type }) } render() { return ( <View style={styles.container}> <TouchableOpacity style={styles.button} onPress={()=>this.jumpPage()}> <Text style={styles.buttonText}> {'Go Second Page(From Right)'} </Text> </TouchableOpacity> <TouchableOpacity style={styles.button} onPress={()=>this.jumpPage('bottom')}> <Text style={styles.buttonText}> {'Go Second Page(From Bottom)'} </Text> </TouchableOpacity> </View> ); } } class SecondPage extends Component { render() { return ( <View style={styles.container}> <TouchableOpacity style={styles.button} onPress={()=>this.props.navigator.pop()}> <Text style={styles.buttonText}> Go Back, From: {this.props.title} </Text> </TouchableOpacity> </View> ); } } // 导航栏的Mapper var NavigationBarRouteMapper = { // 左键 LeftButton(route, navigator, index, navState) { if (index > 0) { //从路由中获取前一个页面的Title,然后作为左边后退按钮的标题 var previousRoute = navState.routeStack[index - 1]; return ( <TouchableOpacity style={styles.navBarLeftButton} underlayColor='transparent' onPress={() => { if (index > 0) { navigator.pop() } }}> <Text style={[styles.navBarText, styles.navBarButtonText]}>{previousRoute.title}</Text> </TouchableOpacity> ); } }, // 右键 RightButton(route, navigator, index, navState) { //如果存在右键方法,则增加右键按钮 if (route.rightBtnClick) return ( <TouchableOpacity style={styles.navBarRightButton} onPress={() => route.rightBtnClick()}> <Text style={[styles.navBarText, styles.navBarButtonText]}> {route.rightText} </Text> </TouchableOpacity> ); }, // 标题 Title(route, navigator, index, navState) { return ( <Text style={[styles.navBarText, styles.navBarTitleText]}> {route.title} </Text> ); } }; class MyTestNavigator extends Component { renderScene(route, navigator) { switch (route.id){ case "firstPage" : return <FirstPage navigator={navigator} title={route.title}/> case "secondPage" : return <SecondPage navigator={navigator} title={route.title}/> } } configureScene(route, routeStack) { if (route.type == 'bottom') { return Navigator.SceneConfigs.FloatFromBottom; } return Navigator.SceneConfigs.FloatFromRight; } render() { return ( <Navigator style={{flex: 1}} initialRoute={{id: 'firstPage', title: "FirstPage"}} configureScene={this.configureScene} renderScene={this.renderScene} navigationBar={ <Navigator.NavigationBar style={[styles.navContainer]} routeMapper={NavigationBarRouteMapper}/>} /> ); } } var styles = StyleSheet.create({ goBack: { width: 25, height: 25, borderLeftWidth: 1, borderBottomWidth: 1, borderColor: "#FFF", transform: [{rotate: "45deg"}], top: 0, left: 15 }, // 页面框架 container: { flex: 1, marginTop: 100, flexDirection: 'column' }, flex: { flex: 1, flexDirection: "row" }, // 导航栏 backRed: { backgroundColor: 'red', }, backBlue: { backgroundColor: 'blue', }, backYellow: { backgroundColor: 'yellow', }, navContainer: { // backgroundColor: 'blue', }, center: { alignItems: "center", justifyContent: "center" }, // 导航栏文字 headText: { color: '#ffffff', fontSize: 22 }, // 按钮 button: { height: 60, marginTop: 10, justifyContent: 'center', // 内容居中显示 backgroundColor: '#ff1049', alignItems: 'center' }, // 按钮文字 buttonText: { fontSize: 18, color: '#ffffff' }, // 左面导航按钮 leftNavButtonText: { color: '#ffffff', fontSize: 18 }, // 右面导航按钮 rightNavButtonText: { color: '#ffffff', fontSize: 18 }, // 标题 title: { fontSize: 18, color: '#000', textAlign: 'center', alignItems: 'center', justifyContent: 'center', fontWeight: 'bold', marginVertical: 9, }, navBar: { backgroundColor: 'white', }, navBarText: { fontSize: 16, marginVertical: 10, }, navBarTitleText: { color: '#373E4D', fontSize: 20, fontWeight: '500', marginVertical: 9, textAlign: "center", alignSelf: "center", backgroundColor: 'yellow', marginLeft: -62 }, navBarLeftButton: { paddingLeft: 10, }, navBarRightButton: { paddingRight: 10, }, navBarButtonText: { color: '#5890FF', }, }); module.exports = MyTestNavigator; // 导出模块
经过测试,Navigator的Title在Android系统下无法居中,不知后续版本是否会修复。如果要居中可以尝试使用其他的定位方式进行居中