目录

  • 集成react-navigation
  • 使用react-navigation

上一篇介绍了如何在已有iOS项目中集成React Native。这一篇我们把上一篇的demo做下拓展,添加点击电影跳转到详情页。页面跳转使用React Native推荐的第三方导航控件:react-navigation

集成react-navigation

  1. 根据官方指引,在终端cd到项目根目录,分别输入以下命令进行集成:

npm install --save react-native-navigation
npm install --save react-native-gesture-handler
react-native link react-native-gesture-handler

  1. 在iOS项目中,打开Podfile文件,添加RCTLinkingIOS:
pod 'React', :path => '../node_modules/react-native', :subspecs => [. . . // other subspecs'RCTLinkingIOS',. . .]

然后执行以下命令安装

pod install
至此,react-navigation集成完毕。

使用react-navigation

  1. 参考官方使用文档,在根目录创建Navigator.js文件,编辑内容如下:
import React from "react";
import { createStackNavigator, createAppContainer } from 'react-navigation'
import HotMovie from './src/page/HotMovie';
import MovieDetail from './src/page/MovieDetail'const AppNavigator = createStackNavigator({Home: HotMovie,Details: MovieDetail},{initialRouteName: "Home"}
)const AppContainer = createAppContainer(AppNavigator);
export default class Navigator extends React.Component {render() {return <AppContainer />;}
}

其中HotMovie为上一篇中创建的电影列表,MovieDetail为新建的电影详情页,具体如下一步

  1. 创建MovieDetail.js文件,路径为./src/page/MovieDetail.js,编辑如下:
import React,{Component} from 'react';
import {StyleSheet,Image,Text,View} from 'react-native';export default class MovieDetail extends Component<Props>{constructor(props){super(props)const { navigation } = propsconst itemId = navigation.getParam('itemId', 'NO-ID')const cover = navigation.getParam('cover')this.state = {detail:null,cover:cover,itemId:itemId}this.fetchData = this.fetchData.bind(this)}componentDidMount(){const requrest_url = "https://movie.douban.com/j/subject_abstract?subject_id="+this.state.itemIdthis.fetchData(requrest_url)}fetchData(requrest_url){fetch(requrest_url).then((response) => response.json()).then((responseJson) => {this.setState({detail:responseJson.subject});})}render(){if (!this.state.detail) {return this.renderLoadingView();}const data =  this.state.detailconst state = this.statereturn(<View><Text style={{fontSize:32,fontWeight:"400",padding:10}}>{data.title}</Text><View style={styles.detailView}><Image style={styles.thumbnail} source={{url:state.cover}}></Image><View style={styles.rightDetai}><Text>导演: {data.directors.join('/')}</Text><Text>评分:{data.rate}</Text><Text>时长:{data.duration}</Text><Text>类型:{this.state.detail.types.join('/')}</Text><Text>主演:{this.getDetaiActor()}</Text></View></View></View>)}renderLoadingView(){return (<View style={styles.container}><Text>正在加载...</Text></View>)}getDetaiActor(){return this.state.detail.actors.slice(0,5).join('/')+' 等'}
}const styles = StyleSheet.create({container: {flex:1,flexDirection:'column',alignItems:'center',justifyContent: 'center',alignItems: 'center',height:300},detailView: {flexDirection:'row',justifyContent: 'flex-start',height:200,paddingLeft:20,paddingTop:10,paddingRight:10,},thumbnail:{width:79.5,height:121.5,},rightDetai:{flexDirection:'column',height:200,marginLeft:10}});
  1. Index.js文件修改为:
import React from 'react';
import { AppRegistry } from 'react-native';
import HotMovie from './src/page/HotMovie';
import MovieDetail from './src/page/MovieDetail'
import Navigator from './Navigator';AppRegistry.registerComponent('Navigator', () => Navigator);
AppRegistry.registerComponent('HotMovie', () => HotMovie);
AppRegistry.registerComponent('MovieDetail', () => MovieDetail);
  1. 在iOS项目中,跳转ViewController.m文件改为如下:
#import "ViewController.h"
#import <React/RCTRootView.h>@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 200, 50)];button.center = self.view.center;[button setTitle:@"跳转RN" forState:0];[button setTitleColor:[UIColor greenColor] forState:0];[button addTarget:self action:@selector(clickButton:) forControlEvents:UIControlEventTouchUpInside];[self.view addSubview:button];
}- (void)clickButton:(UIButton*)button{NSURL *jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.bundle?platform=ios"];RCTRootView *rootView =[[RCTRootView alloc] initWithBundleURL: jsCodeLocationmoduleName: @"Navigator"initialProperties: nillaunchOptions: nil];UIViewController *vc = [[UIViewController alloc] init];vc.view = rootView;[self presentViewController:vc animated:YES completion:nil];
}
@end
  1. 在HotMovie.js中添加点击事件,HotMovie.js完整代码如下:
import React, { Component } from 'react';
import {StyleSheet, Image, Text, View, FlatList,TouchableOpacity} from 'react-native';
import { createStackNavigator, createAppContainer } from 'react-navigation'var REQUEST_URL = "https://movie.douban.com/j/search_subjects?type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=0"export default class HotMovie extends Component<Props> {_onItemClick(item) {this.props.navigation.navigate('Details',{itemId:item.id,cover:item.cover,title:item.title})}constructor(props){super(props);this.state = {movies:null,}this.renderMovie = this.renderMovie.bind(this)this.fetchData = this.fetchData.bind(this)}componentDidMount(){this.fetchData()}fetchData(){fetch(REQUEST_URL).then((response) => response.json()).then((responseJson) => {this.setState({movies:responseJson.subjects});})}render() {if (!this.state.movies) {return this.renderLoadingView();}return (<FlatListdata={this.state.movies}renderItem={this.renderMovie}style={styles.list}keyExtractor={item => item.id}/>);}renderLoadingView(){return (<View style={styles.container}><Text>正在加载...</Text></View>)}renderMovie({item}){return(<TouchableOpacity style={styles.item} onPress={() => this._onItemClick(item)}><Image source={{url:item.cover}} style={styles.thumbnail}/><View style={styles.itemRight}><Text>{item.title}</Text><Text>{item.rate}</Text></View></TouchableOpacity>)}
}const styles = StyleSheet.create({container: {flex:1,flexDirection:'row',alignItems:'center',justifyContent: 'center',alignItems: 'center',},item:{marginTop:1,flexDirection:'row',alignItems:'center',justifyContent: 'flex-start',height:100,backgroundColor:'lightgray',paddingLeft:10},thumbnail:{width:53,height:81,backgroundColor:'lightgray'},itemRight:{height:100,justifyContent: 'center',alignItems:'center',paddingLeft:10},list: {backgroundColor: "#F5FCFF"}
});

其中this.props.navigation.navigate('Details')即为react-navigation的导航跳转方法,但此方法不能跳转相同的页面(会没有效果),如果要多次push同样的页面,需要改为:

this.props.navigation.push('Details')

导航返回的话:

this.props.navigation.goBack()
  1. 设置导航标题

根据不同的需求,我们先看下官方的示例:

  • 如果标题是固定的,定义一个名为navigationOptions的static的属性,返回一个包含配置的对象,如:
class HomeScreen extends React.Component {static navigationOptions = {title: 'Home',};/* render function, etc */
}
  • 如果是需要从上层参数中获取,代码如:
class DetailsScreen extends React.Component {static navigationOptions = ({ navigation }) => {return {title: navigation.getParam('otherParam', 'A Nested Details Screen'),};};/* render function, etc */
}
  • 如果要修改标题,代码如:
<Buttontitle="Update the title"onPress={() => this.props.navigation.setParams({otherParam: 'Updated!'})}/>
  • 如果需要修改样式,代码如::
class HomeScreen extends React.Component {static navigationOptions = {title: 'Home',headerStyle: {backgroundColor: '#f4511e',},headerTintColor: '#fff',headerTitleStyle: {fontWeight: 'bold',},};/* render function, etc */
}
  • 以上只是设置了首页的导航栏样式,我们希望全局设置,那直接回到最前面createStackNavigator代码处,修改:
const RootStack = createStackNavigator({Home: HomeScreen,Details: DetailsScreen,},{initialRouteName: 'Home',/* The header config from HomeScreen is now here */defaultNavigationOptions: {headerStyle: {backgroundColor: '#f4511e',},headerTintColor: '#fff',headerTitleStyle: {fontWeight: 'bold',},},}
);
  • 有时,我们想把标题改为自定义控件,例如显示图片或者按钮,我们可以这样:
class LogoTitle extends React.Component {render() {return (<Imagesource={require('./spiro.png')}style={{ width: 30, height: 30 }}/>);}
}class HomeScreen extends React.Component {static navigationOptions = {// headerTitle instead of titleheaderTitle: <LogoTitle />,};/* render function, etc */
}

回到我们的demo示例,我们希望整个App导航栏的背景颜色值是#f4511e,文字为白色,故在Navigator.js中统一配置,Navigator.js完整代码如下:

import React from "react";
import { createStackNavigator, createAppContainer } from 'react-navigation'
import HotMovie from './src/page/HotMovie';
import MovieDetail from './src/page/MovieDetail'const AppNavigator = createStackNavigator({Home: HotMovie,Details: MovieDetail},{defaultNavigationOptions: {headerTintColor: '#fff',headerStyle: {backgroundColor: '#f4511e',},headerTitleStyle: {fontWeight: 'bold',},},navigationOptions: {tabBarLabel: 'Home!',},}
)const AppContainer = createAppContainer(AppNavigator);
export default class Navigator extends React.Component {render() {return <AppContainer />;}
}

首页(电影列表)的导航栏标题为指定图片movie.png (对应路径为:项目根目录/src/images/movie.png),故修改HotMovie.js为:

import React, { Component } from 'react';
import {StyleSheet, Image, Text, View, FlatList,TouchableOpacity} from 'react-native';
import { createStackNavigator, createAppContainer } from 'react-navigation'var REQUEST_URL = "https://movie.douban.com/j/search_subjects?type=movie&tag=%E7%83%AD%E9%97%A8&sort=recommend&page_limit=20&page_start=0"class LogoTitle extends React.Component {render() {return (<Imagesource={require('../image/movie.png')}style={{ width: 30, height: 30 }}/>);}
}export default class HotMovie extends Component<Props> {static navigationOptions = {headerTitle: <LogoTitle />,};//....省略代码
}const styles = StyleSheet.create({//...省略代码
});

在电影详情页,我们根据上一页面传递来的电影名称参数来设置标题,缺省值为电影详情:

import React,{Component} from 'react';
import {StyleSheet,Image,Text,View} from 'react-native';export default class MovieDetail extends Component<Props>{static navigationOptions = ({ navigation }) => {return {title:navigation.getParam('title','电影详情')}}//...省略代码
}const styles = StyleSheet.create({//...省略代码
});

完整源代码:https://github.com/dolacmeng/RNProject/tree/master
运行效果:

【React Native】react-navigation导航使用方法相关推荐

  1. vscode 连接夜神模拟器 运行 react native项目 (很简单的方法)

    前言:我这种方式不需要过多配置,只是需要先启动Android studio ,之后再启动vsCode 准备阶段:下载夜神模拟器 1. 开启夜神服务 进入到夜神安装的bin目录下,执行 nox_adb. ...

  2. html转换react native,React native HTML entities

    I'm fetching some data in app from WordPress site successfully. Some entities like "„" rea ...

  3. React Native顶|底部导航使用小技巧

    导航一直是App开发中比较重要的一个组件,ReactNative提供了两种导航组件供我们使用,分别是:NavigatorIOS和Navigator,但是前者只能用于iOS平台,后者在ReactNati ...

  4. react native 的底部导航栏以及跳转页面带参数

    不知不觉又过去了一周,这周依旧是用RN来开发APP,中间遇到很多坑,不过这段时间还是忙,慢慢总结吧,写出一点是一点.写博客除了分享,在开始写之前也是自己对于这段时间学习的总结,重新看代码,理顺思路,这 ...

  5. React Native 的顶部导航栏和底部导航栏目

    说来也是惭愧,本来关于底部导航栏,我已经写过一篇博客,只不过那篇更偏向于入门一些,当时一实现功能之后就迫不及待的分享给大家了.地址在这儿:http://blog.csdn.net/LJFPHP/art ...

  6. 如何在React Native中使用react-navigation 5处理导航

    React-navigation is the navigation library that comes to my mind when we talk about navigation in Re ...

  7. 我在React Native中构建时获得的经验教训

    by Amanda Bullington 通过阿曼达·布林顿(Amanda Bullington) 我在React Native中构建时获得的经验教训 (Lessons I learned while ...

  8. 如何在React Native中构建项目并管理静态资源

    by Khoa Pham 通过Khoa Pham 如何在React Native中构建项目并管理静态资源 (How to structure your project and manage stati ...

  9. H5、React Native、Native应用对比分析

    @王利华,vczero "存在即合理".凡是存在的,都是合乎规律的.任何新事物的产生总要的它的道理:任何新事物的发展总是有着取代旧事物的能力.React Native来的正是时候, ...

最新文章

  1. 纯CSS实现蓝色圆角下拉菜单
  2. Redis5新特性Streams作消息队列
  3. nx二次开发c语言,NX二次开发-UFUN API函数编程基础
  4. 后端返回页面ajax的处理
  5. MongoDB简单概述
  6. 截图工具当前未在计算机上运行 请重启_截图并订在屏幕上 用作对比、对照、参考,非常实用...
  7. reactjs安装并在脚手架中使用 material-ui/core
  8. 扫雷win10_windows扫雷游戏原来是一道数学难题!
  9. Python干货 | 制作遥感影像图
  10. SLAM中双目三角化
  11. 勤于奋:国外LEAD账号申请细节
  12. JavaScript 整分或者指定时间执行操作
  13. Applet中签名与未签名代码的混合使用带来的问题
  14. 租户隔离怎么做MYSQL_基于JPA实现SaaS多租户模式的数据存储——共享数据库,隔离数据架构...
  15. 你知道linux的复制命令吗?cp
  16. 基于KVM的SRIOV直通配置及性能测试
  17. 2022年全国职业院校技能大赛赛项比赛时间、承办校信息统计表(第二批)
  18. java Vector 过时了_为什么Java Vector(和Stack)类被认为已过时或已弃用?
  19. 杰奇cms章节分页怎么实现(主要针对2.4版本)
  20. 三维电子沙盘数字沙盘元宇宙大数据人工智能无人机倾斜摄影三维全景建模第17课

热门文章

  1. 输入重定向,输出重定向,管道相关内容及实现方法
  2. git---远程仓库版本回滚
  3. SecureCRT中sqlplus,使用Backspace删除时 ^H^H
  4. 关于PCA算法的一点学习总结
  5. Oracle EBS R12 运行adadmin 安装中文语言包过程中意外中断后的处理
  6. 小牛生产小牛的问题解决集粹
  7. css布局中的居中问题
  8. libev源码解析——定时器原理
  9. Ubuntu定时任务crontab命令介绍
  10. C++中局部类的使用