createStackNavigator
使用createStackNavigator
来创建页面的跳转栈路径进行追踪
通过createStackNavigator来对路由进行配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const RootStack = createStackNavigator({ // 第一个对象用于对页面的路由表进行配置 Home: HomeScreen, Details: DetailsScreen }, { // 通过第二个参数来对页面进行精细化配置 // 配置页面进入的路由 initialRouteName: 'Home' })
export default class App extends React.Component { render() { return <RootStack /> } }
|
路由页面跳转
页面的路由跳转可以通过多种方式, 其中一种最简单粗暴的方法就是通过onPress
方法
1 2 3 4 5 6
| onPress = { () => { // 跳转其实就是调用父组件中navigator对象中的navigate方法 return this.props.navigation.navigate('Details') } }
|
上面是一个跳转到Details
页面的方式, 还有其他几种方法
1 2 3 4
| // 往回跳转 this.props.navigation.goBack() // 回到堆栈中的最顶层 this.props.navigation.popToTop()
|
另一点需要注意的是, 因为react navigation
的机制问题, 当前页面中跳转当前页面, 是没有任何反应的
路由的页面传参
通过对navigate
方法传递第二个参数的方式, 可以实现页面跳转的参数传递
1 2 3 4
| this.props.navigation.navigate('Details', { itemId: 86, otherParam: 'anything you want here', })
|
同样的, 接收参数也是需要使用类似的方式
1 2
| const itemId = navigation.getParam('itemId', 'NO-ID'); const otherParam = navigation.getParam('otherParam', 'some default value');
|
通过navigation
的getParam
方法进行参数的接收, 第一个参数为参数名称, 第二个参数为默认值
为页面增加页面参数
为页面增加参数可以直接使用navigationOptions
, 对其进行赋值即可
1 2 3
| static navigationOptions = { title: 'Detail' }
|
同样的, 我们也可以使用函数的方式对title进行赋值
1 2 3 4 5
| static navigationOptions = ({navigation}) => { return { title: navigation.getParam('otherParam', 'a nested title') } }
|
由于这个特性, 我们就可以很方便地对页面的标题进行设置了, 比如说, 当我们点击某个按钮的时候
1 2 3 4 5 6 7
| onPress={ () => { return this.props.navigation.setParams({ otherParam: 'changed' }) } }
|
点击之后重新设置了navigation中的参数
为页面的标题增加自定义的样式
直接为navigationOptions
额外传递参数即可
1 2 3 4 5 6 7 8 9 10
| // 整个头部的样式 headerStyle: { backgroundColor: '#f4511e', }, // 头部的标题颜色 headerTintColor: '#fff', // 头部标题的样式 headerTitleStyle: { fontWeight: 'bold', },
|
一般情况下, 我们的标题的样式在整个项目工程中是一样的, 所以此时我们可以直接在根路由中去为页面整体做样式的设置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| const RootStack = createStackNavigator({ Home: HomeScreen, // 通过createStackNavigator来进行页面的路由配置 Details: DetailsScreen }, { initialRouteName: 'Home', // 初始默认的路由 navigationOptions: { headerStyle: { backgroundColor: '#f4511e', }, headerTintColor: '#fff', headerTitleStyle: { fontWeight: 'bold', }, }, });
|
自定义跳转的标题图标
对于页面的标题, 图标, 按钮等功能, 我们都可以对其进行定制, 下面是定制我们的标题的样式的例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| // 我们定义一个组件, 用于显示在标题上 class LogoTitle extends React.Component { render() { return (<Image source={require('./assets/delete.png')} style={{ width: 30, height: 30 }}/>); } }
...省略... static navigationOptions = { headerTitle: <LogoTitle />, // 同样的, 对标题左侧和右侧, 也是一样可以进行设置的 headerRight: ( <Button onPress={() => alert('This is a button!')} title="Info" color="#000" /> ), headerLeft: ( <Button onPress={() => alert('This is a button!')} title="Info" color="#000" /> ), }
|
页面的标题向页面传参方式
页面标题向页面内的传参方式稍复杂, 需要定义一个中间参数, 通过每次对中间参数函数的方式去调用页面内的函数
需要注意的是, 此时标题的navigationOptions
必须为函数, 否则无法实现此功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| const navigaionOptions = ({navigaion}) => { const params = navigation.state.params || {} return { headerTitle: <LogoTitle />, headerRight: ( <Button onPress={params.increaseCount} title="add one" color="#000" /> ), } }
// state不需要放在constructor里面? state = { count = 0 }
// 在页面声明周期初始化的时候, 初始化设置increaseCount这个变量, 用于对页面进行初始化配置 componentWillMount() { this.props.navigation.setParams({ increaseCount: this._increaseCount }) }
_increaseCount = () => { this.setState({ count: this.state.count + 1 }) }
|
全屏模态框
全屏模态框会暂时阻止原来页面的交互流程, 而直接开始模态框中的交互
我们对页面分为两个部分, 一个是页面分类, 另一个是模态框的分类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| const MainStack = createStackNavigator({ Home: HomeScreen, // 通过createStackNavigator来进行页面的路由配置 Details: DetailsScreen }, { initialRouteName: 'Home', // 初始默认的路由 navigationOptions: { headerStyle: { backgroundColor: '#f4511e', }, headerTintColor: '#fff', headerTitleStyle: { fontWeight: 'bold', }, }, });
const RootStack = createStackNavigator( { // 页面堆栈 Main: { screen: MainStack, }, // 模态框堆栈 MyModal: { screen: ModalScreen, }, }, { mode: 'modal', headerMode: 'none', } );
export default class App extends React.Component { render() { return <RootStack/>; } }
|
这样配置好之后, 需要使用modal全屏页面的时候, 直接调用跳转逻辑即可
1 2 3 4 5 6 7
| // 在页面中 <Button title = "Go to Modal" onPress = { () => this.props.navigation.navigate('MyModal') } />
|
tab导航
tab导航的定义方式很简单, 通过从react-navigation中引入不同的配置函数即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import {createBottomTabNavigator} from 'react-navigation';
// 定义页面的tab堆栈 const TabStack = createBottomTabNavigator({ // 定义的键值对中, 键名默认为tab的名称, 可在页面中定义title来覆盖这个名称 Home111: HomeScreen, Details: SettingsScreen })
// 同样的, 将这个堆栈从app根组件中渲染即可 export default class App extends React.Component { render() { return <TabStack/>; } }
|
抽屉导航