【新东网技术大咖带您走进React Native】用它就可通吃移动端开发
发布时间: 2016-09-09 11:58:01
文/闫立帮 华西研发部
新东网自2001年成立以来,掌握大数据、云计算、通信、物联网及区块链等信息技术,拥有一支逾16年经验的强大IT团队。为沉淀企业技术实力,继续发挥行业优势,《东网快讯》特邀新东网技术大咖带您走进这些先进信息技术,揭秘新东网16年来的技术成果,每周五发布。
一、React Native 是什么
React Native 是 Facebook 推出的一个用 Java 语言就能同时编写 ios,android,以及后台的一项技术。用大白话说,就是从此一名程序员只用这一门技术,就可以同时写出 android app,ios app,以及后台应用程序。而app 也能做到向网页程序那样随时都能更新了。是不是很牛逼?是不是很牛逼?是不是很牛逼?重要的事问三遍!嗯,真的很牛逼。
那么我们来看看React Native 受到了如此大的关注,它的优越性到底在什么地方呢?React Native整套解决方案完成了江湖统一,FaceBook 也号称这门技术是 “Learn Once,Write AnyWhere”,即学习成本只有一次,却完成了所有开发角色的统一。
1.app 将来都是可像网页一样随时更新,随时发布。
2.对于一名开发人员,将再也没有前端、终端、后台的区分,他所关注的就是做一整套应用程序,人力资源将得到最大程度的整合与释放。
3.代码复用将会是主旋律,因为是一种语言,大家重复造轮子的成本会越来越节省。
目前,React Native 也还是有一些缺点的,比如他的 sdk 组件包 size 还比较大,crash 还比较多,在 ios 上支持的内容已经相当不错了,但在android上 支持则还属于初级阶段。不过,这些都只是一个新技术刚刚诞生时存在的普遍性问题,相信随着技术不断地发展与完善,将都不再是问题。
二、React Native 的技术优势
React Native作为Facebook推出的一个开源框架,实现以JavaScript开发移动应用,具有如下优势:
1. JavaScript使用门槛低、普及率高 。
2. 使用JavaScript开发,开发成本低:移动端(iOS和Android平台上),由于内置浏览器都采用Webkit内核,因而在使用JavaScript开发时,完全无需考虑浏览器兼容问题,进一步降低了JavaScript的开发成本。
3. React Native采用了JSX语法糖工具。JSX是一种语法转换工具,能够将XML标签转换为JavaScript代码。这意味着,你可以在JavaScript里像写XML一样去写JavaScript代码,不用手动拼接XML格式的字符串,不用显示地创建标签和执行插入标签操作,而且这样写出来的代码可读性非常强,降低维护成本。
4. 原生UI,UI交互效率高。React Native未采用WEB模式,而是使用JavaScript去开发原生应用。React Native自己实现了一套与原生语言通讯的机制,将JavaScript视为数据源,用原生语言去调用数据源,然后用原生UI来展示,用原生语言来实现事件机制,这样便不再有浏览器单线程、DOM渲染效率低导致的交互体验差的问题。由于JavaScript和原生语言的运行效率很高,因而应用交互体验非常好,堪比原生应用。
5. React Ntive与Hybird app、Native APP 的优势对比分析
React Ntive与Hybird app优势对比分析:
1) 不用Webview,彻底摆脱了Webview让人不爽的交互和性能问题
2)有较强的扩展性,这是因为Native端提供的是基本控件,JS可以自由组合使用
3) 可以直接使用Native原生的「牛逼」动画(在FB Group这个app里面,面板滑出带一点果冻弹动,面板基于某个点展开这种动画随处可见,这种动画用Native code来做小菜一碟,但是用Web来做就难上加难)。
优势相对于Native app: 可以通过更新远端JS,直接更新app。
三、React Native 的应用实例
这里选用携程的App首页作为例子。整个页面我们可以分为头部导航栏、 图片轮播、 9宫格、底部活动这几个部分,大致如下:
1、头部导航栏
在React-Native中实现头部导航栏很简单,只要使用NavigatorIOS组件即可。现在开工。
1、我们在index.ios.js中添加如下代码;同时创建文件夹pagaes和pages下创建Index.js
var React = require(‘react-native‘);
var Index = require(‘./pages/Index‘);
var {
NavigatorIOS,
AppRegistry,
StyleSheet,
} = React;
var NV = React.createClass({
render: function(){
return(
style={styles.container}
initialRoute={{
title: ‘首页‘,
component: Index,
}}
/>
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1,
}
});
AppRegistry.registerComponent(‘HelloWorld‘, () => NV);
分析代码:
(1)require:引入外部模块,就像,引入我们自己创建的/pages/Index.js一样。
(2)引入定义NavigatorIOS、AppRegistry、StyleSheet组件和类。
(3)在render中调用NavigatorIOS组件,initialRoute是初始化路由,title是当前页面的头部标题;component是当前路由下显示的组件;
(4)注意:这里NavigatorIOS的style需要设置大小,比如这里设置是flex:1,否则就不能显示内容主体;
(5)最后我们需要注册当前应用:AppRegistry.registerComponent(‘HelloWorld‘, () => NV);
2、创建Index.js文件,文件的内容如下, module.exports就暴露了Index模块。
效果如下图:
2、图片轮播
这里图片轮播使用的是第三方组件react-native-swiper,当然React-Native是支持transform可以直接实现一套。我们启动npm命令行,在项目的根目录使用如下命令安装模块。
$ npm react-native-swiper --save
安装完成后,我们需要完成轮播功能。因为可以到github看看swiper暴露的接口和参数。github地址是:https://github.com/leecade/react-native-swiper
(1)引入swiper,前面也提到了require.
var Swiper = require(‘react-native-swiper‘);
(2)使用swiper,将轮播图封装成单独的组件
var sliderImgs = [
‘http://images3.c-ctrip.com/SBU/apph5/201505/16/app_home_ad16_640_128.png‘,
‘http://images3.c-ctrip.com/rk/apph5/C1/201505/app_home_ad49_640_128.png‘,
‘http://images3.c-ctrip.com/rk/apph5/D1/201506/app_home_ad05_640_128.jpg‘
];
var Slider = React.createClass({
render: function(){
return (
);
}
});
(3)这样我们可以直接在render的时候直接用:
3、完成第一个9宫格布局
4个九宫格都是一样,实可以封装成组件,这里采用拷贝的形式,开发一个,其他3个就ok的,会偷懒是一种智慧。分析下布局:
(1)首先是3个列在一行的布局,那么外层组件是需要flexDirection: ‘row‘,各占据宽度的1/3,即各自flex:1;
(2)每个列内又分两行, 需要每个行都是flex:1,各占据高度的一半;
(3)第一列是文字图片组合,其余都是文字组合;
(4)所有行内元素都是水平、垂直居中;
(5)这里使用了个TouchableHighlight组件,是为了出发onPress事件,类似于click或者touch事件。
4、样式类
说完了布局的原理,这里需要贴上样式仅供参考:
var styles = StyleSheet.create({
//container
container:{
backgroundColor:‘#F2F2F2‘,
flex:1,
},
//slider
wrapper: {
height:80,
},
slide: {
height:80,
resizeMode: Image.resizeMode.contain,
},
//sbu
sbu_view:{
height:84,
marginLeft: 5,
marginRight:5,
borderWidth:1,
borderRadius:5,
marginBottom:10,
flexDirection:‘row‘,
},
sbu_red:{
backgroundColor: ‘#FA6778‘,
borderColor:‘#FA6778‘,
marginTop:-70,
},
sbu_blue:{
backgroundColor: ‘#3D98FF‘,
borderColor:‘#3D98FF‘,
},
sbu_green:{
backgroundColor: ‘#5EBE00‘,
borderColor:‘#5EBE00‘,
},
sbu_yellow:{
backgroundColor: ‘#FC9720‘,
borderColor:‘#FC9720‘,
},
sbu_flex:{
flex:1,
},
sbu_borderRight:{
borderColor:‘#fff‘,
borderRightWidth: 0.5,
},
sbu_icon_img:{
height:40,
width:40,
resizeMode:Image.resizeMode.contain,
},
sub_con_flex:{
flex:1,
justifyContent: ‘center‘,
alignItems: ‘center‘,
},
sub_text:{
justifyContent:‘center‘,
},
font16:{
fontSize:17,
color:‘#FFF‘,
fontWeight:‘900‘,
},
sbu_borderBottom:{
borderBottomWidth:0.5,
borderBottomColor:‘#fff‘,
},
img_view:{
height:62,
marginLeft:5,
marginRight:5,
flexDirection: ‘row‘,
marginBottom:20,
backgroundColor:‘#fff‘,
},
img_flex:{
flex:1,
borderWidth:1,
borderColor:‘#ccc‘,
},
img_wh: {
height:59,
borderRightWidth:0,
resizeMode:Image.resizeMode.contain,
}
});
着重说下resizeMode:Image.resizeMode.contain。在React-Native中图片的大小是不会根据给定一个宽度或者高度而自适应大小的,因此我们需要让图片根据宽度或者高度来自适应,那么可以使用resizeMode:Image.resizeMode.contain。