React Native移动框架功能研究

此篇只研究React
Native框架的功能。

一、React
Natvie
是什么

React
Native是使用React(或者说JS)来开发原生APP的框架。

二、React
Native
的愿景

1.提供一直的跨平台开发原生APP的一直体验。

2.使用JS和React提高跨平台开发效率。

三、React
Native
提供的特性

1.提供了丰富的原生组件,可以是APP获得平台一致的视觉效果和体验,同时获得最佳的性能和流畅性。


// iOS & Android

var React = require('react-native');
var { ScrollView, TouchableHighlight, Text } = React; var TouchDemo = React.createClass({
render: function() {
return (
<ScrollView>
<TouchableHighlight onPress={() => console.log('pressed')}>
<Text>Proper Touch Handling</Text>
</TouchableHighlight>
</ScrollView>
);
},
});

2.JS代码和原生平台之间的所有操作都是异步执行的,原生模块可以根据需要自由创建线程。同时两者之间的通讯是完全可序列化的,这使其可以借助Chorme开发这工具进行调试。

3.提供强大的触控事件处理系统,可以在复杂的UI层次结构下方便的处理触控事件。

// iOS & Android

var React = require('react-native');
var { ScrollView, TouchableHighlight, Text } = React; var TouchDemo = React.createClass({
render: function() {
return (
<ScrollView>
<TouchableHighlight onPress={() => console.log('pressed')}>
<Text>Proper Touch Handling</Text>
</TouchableHighlight>
</ScrollView>
);
},
});
4.通过Flexbox简化UI布局,提供高性能机制声明样式和布局,并可直接应用到组件中。
// iOS & Android

var React = require('react-native');
var { Image, StyleSheet, Text, View } = React; var ReactNative = React.createClass({
render: function() {
return (
<View style={styles.row}>
<Image
source={{uri: 'http://facebook.github.io/react/img/logo_og.png'}}
style={styles.image}
/>
<View style={styles.text}>
<Text style={styles.title}>
React Native
</Text>
<Text style={styles.subtitle}>
Build high quality mobile apps using React
</Text>
</View>
</View>
);
},
});
var styles = StyleSheet.create({
row: { flexDirection: 'row', margin: 40 },
image: { width: 40, height: 40, marginRight: 10 },
text: { flex: 1, justifyContent: 'center'},
title: { fontSize: 11, fontWeight: 'bold' },
subtitle: { fontSize: 10 },
});
5.提供灵活的机制,方便自定义原生视图和模块。
四、React Native的功能
1.样式
React Native在JS中定义和引用样式。可以通过StyleSheet定义样式
var styles = StyleSheet.create({
base: {
width: 38,
height: 38,
},
background: {
backgroundColor: '#222222',
},
active: {
borderWidth: 2,
borderColor: '#00ff00',
},
});
在组件中使用样式
<Text style={styles.base} />
<View style={styles.background} />
同时可以接受多个样式,后边的会覆盖前边的样式
<View style={[styles.base, styles.background]} />
可以结合表达式控制是否应用样式
<View style={[styles.base, this.state.active && styles.active]} />
也可以直接在元素中声明样式,但是每次渲染都会重建样式,影响性能。
<View
style={[styles.base, {
width: this.state.width,
height: this.state.width * this.state.aspectRatio
}]}
/>
样式也可以作为参数传递
var List = React.createClass({
propTypes: {
style: View.propTypes.style,
elementStyle: View.propTypes.style,
},
render: function() {
return (
<View style={this.props.style}>
{elements.map((element) =>
<View style={[styles.element, this.props.elementStyle]} />
)}
</View>
);
}
}); // ... 在别的文件中引用List组件 ...
<List style={styles.list} elementStyle={styles.listElement} />
2.图片
加载本地静态图片,图片基于当前js的目录。如果带有平台相关的扩展名,则系统自动根据当前的系统平台自动加载相关的图片,例如my-icon.ios.png
<Image source={require('./my-icon.png')} />
使用@2x,@3x这样的文件名后缀,可以为不同的屏幕精度提供图片
可以在React Native中直接使用内嵌到APP中的图片资源
<Image source={{uri: 'app_icon'}} style={{width: 40, height: 40}} />
可以加载网络图片,但是需要手动指定图片大小
<Image source={{uri: 'https://facebook.github.io/react/img/logo_og.png'}}
style={{width: 400, height: 400}} />
通过将元素嵌套到Image中实现背景图片
return (
<Image source={...}>
<Text>Inside</Text>
</Image>
);
3.手势触控系统
提供Touchable和TouchableHighlight来定义可触控控件。响应者的声明周期如下:
是否愿意成为响应者
View.props.onStartShouldSetResponder(开始触摸的时候是否愿意)
View.props.onMoveShouldSetResponder(如果不是响应者,则每次开始移动触控点时询问是否原因)
如果愿意成为响应者,则接下来开始尝试成为响应者
View.props.onResponderGrant(成功成为响应者)
View.props.onResponderReject(被拒绝成为响应者)
如果成功成为响应者,则开始具体的响应触控事件
View.props.onResponderMove(响应屏幕手指移动)
View.props.onResponderRelease(响应屏幕手指离开)
View.props.onResponderTerminationRequest(其他组件请求接替响应者,返回true则释放自己响应者角色)
View.props.onResponderTerminate(响应者角色已交出) onStartShouldSetResponder与onMoveShouldSetResponder是以冒泡的形式调用的,即嵌套最深的节点最先调用。如果某个父View会希望能先成为响应者。我们可以利用“捕获期”来解决这一需求。
View.props.onStartShouldSetResponderCapture
View.props.onMoveShouldSetResponderCapture
4.动画
用于全局的布局动画LayoutAnimation,和用于创建更精细的交互控制的动画Animated。Animated库使得开发者可以非常容易地实现各种各样的动画和交互方式,并且具备极高的性能。它包括两个值类型,Value用于单个的值,而ValueXY用于向量值;还包括三种动画类型,spring,decay,还有timing,以及三种组件类型,View,Text和Image。我们可以使用Animated.createAnimatedComponent方法来对其它类型的组件创建动画。
class Playground extends React.Component {
constructor(props: any) {
super(props);
this.state = {
bounceValue: new Animated.Value(0),
};
}
render(): ReactElement {
return (
<Animated.Image // 可选的基本组件类型: Image, Text, View
source={{uri: 'http://i.imgur.com/XMKOH81.jpg'}}
style={{
flex: 1,
transform: [ // `transform`是一个有序数组(动画按顺序执行)
{scale: this.state.bounceValue}, // 将`bounceValue`赋值给 `scale`
]
}}
/>
);
}
componentDidMount() {
this.state.bounceValue.setValue(1.5); // 设置一个较大的初始值
Animated.spring( // 可选的基本动画类型: spring, decay, timing
this.state.bounceValue, // 将`bounceValue`值动画化
{
toValue: 0.8, // 将其值以动画的形式改到一个较小值
friction: 1, // Bouncier spring
}
).start(); // 开始执行动画
}
}
多个动画可以通过parallel(同时执行)、sequence(顺序执行)、stagger和delay来组合使用。
Animated.sequence([            // 首先执行decay动画,结束后同时执行spring和twirl动画
Animated.decay(position, { // 滑行一段距离后停止
velocity: {x: gestureState.vx, y: gestureState.vy}, // 根据用户的手势设置速度
deceleration: 0.997,
}),
Animated.parallel([ // 在decay之后并行执行:
Animated.spring(position, {
toValue: {x: 0, y: 0} // 返回到起始点开始
}),
Animated.timing(twirl, { // 同时开始旋转
toValue: 360,
}),
]),
]).start();
LayoutAnimation允许在全局范围内创建和更新动画,它常用来更新flexbox布局。
var App = React.createClass({
componentWillMount() {
// 创建动画
LayoutAnimation.spring();
}, getInitialState() {
return { w: 100, h: 100 }
}, _onPress() {
// 让视图的尺寸变化以动画形式展现
LayoutAnimation.spring();
this.setState({w: this.state.w + 15, h: this.state.h + 15})
}, render: function() {
return (
<View style={styles.container}>
<View style={[styles.box, {width: this.state.w, height: this.state.h}]} />
<TouchableOpacity onPress={this._onPress}>
<View style={styles.button}>
<Text style={styles.buttonText}>Press me!</Text>
</View>
</TouchableOpacity>
</View>
);
}
});
如果对性能要求比较高,setNativeProps方法可以使我们直接修改基于原生视图的组件的属性,而不需要使用setState来重新渲染整个组件树,从而可以使我们获得较好的性能。此时应该注意被render重新调用的时候覆盖掉。
5.提供的调试工具
开发者菜单
Chrome开发者工具
React开发工具插件
FPS监视器
6.自动化测试
使用Jest进行单元测试,使用Travis作为持续集成系统。
集成测试和快照测试只使用IOS。
7.JS环境
在IOS、Android模拟器和真机上,使用的是JavaScriptCore。
在Chorme调试时,代码运行在V8引擎中。
React Native从0.5.0版本开始已经内置Babel转换器,使我们可以使用最新的js语法编写代码。
8.导航器
官方提供提供通用跨平台的Navigator,js编写方便扩展。
开源社区提供的NavigatorIOS,只能在IOS中使用,依赖Object-c,积压bug无人解决,不建议使用。
9.特定平台代码
将代码放在特定平台的文件夹下
/common/components/
/android/components/
/ios/components/
组件命名中添加平台标志
BigButtonIOS.js
BigButtonAndroid.js
特定平台扩展名
BigButton.ios.js
BigButton.android.js 在js中判断当前平台
var {Platform} = React;

var styles = StyleSheet.create({
height: (Platform.OS === 'ios') ? 200 : 100,
});
五、已知存在的问题
模块和原生视图缺失,比如Maps、Spinner等

 某些属性仅仅支持单个平台

 有一些已经存在的组件和API没能进行统一抽象为通用的,比如ActivityIndicatorIOS和ProgressBarAndroid

    overflow样式在Android中无法使用

 不支持Android M(6.0)的权限

    NG图片的内存问题

												

React Native移动框架功能研究的更多相关文章

  1. react native一键分享功能实现&原理和注意点(支持微信、qq、新浪微博等)

    目前手机使用的一键分享SDK比较主流的有两个:一个是ShareSDK,另一个是友盟分享. 又因为友盟功能比较多且比较全,比如说友盟统计.友盟推送等,所以本文重点介绍的是友盟分享功能在rn上的应用以及要 ...

  2. iOS Contact框架功能研究

    兄弟们,直接复制,感谢度娘,感谢谷哥!!! 1.读取联系人通讯录 /** *  读取联系人通讯录 */ -(NSMutableArray*)getContactList{ NSMutableArray ...

  3. 跨平台框架与React Native基础

    跨平台框架 什么是跨平台框架? 这里的多个平台一般是指 iOS 和 Android . 为什么需要跨平台框架? 目前,移动开发技术主要分为原生开发和跨平台开发两种.其中,原生应用是指在某个特定的移动平 ...

  4. taro之React Native 端开发研究

    初步结论:如果想把 React Native 集成到现有的原生项目中,不能使用taro的React Native 端开发功能(目前来说不能实现,以后再观察).   RN开发有2种模式: 1.一是原生A ...

  5. React Native 在 Airbnb(译文)

    在Android,iOS,Web和跨平台框架的横向对比中,React Native本身是一个相对较新且快速开发移动的平台.两年后,我们可以肯定地说React Native在很多方面都是革命性的.这是移 ...

  6. React Native环境配置和简单使用

    # 前言 学习本系列内容需要具备一定 HTML 开发基础,没有基础的朋友可以先转至 HTML快速入门(一) 学习 本人接触 React Native 时间并不是特别长,所以对其中的内容和性质了解可能会 ...

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

    每日更新关注:http://weibo.com/hanjunqiang  新浪微博!iOS开发者交流QQ群: 446310206 "存在即合理".凡是存在的,都是合乎规律的.任何新 ...

  8. 《React Native 精解与实战》书籍连载「React Native 底层原理」

    此文是我的出版书籍<React Native 精解与实战>连载分享,此书由机械工业出版社出版,书中详解了 React Native 框架底层原理.React Native 组件布局.组件与 ...

  9. Hybrid APP基础篇(二)->Native、Hybrid、React Native、Web App方案的分析比较

    说明 Native.Hybrid.React.Web App方案的分析比较 目录 前言 参考来源 前置技术要求 楔子 几种APP开发模式 概述 Native App Web App Hybrid Ap ...

随机推荐

  1. Codeforces 738D. Sea Battle 模拟

    D. Sea Battle time limit per test: 1 second memory limit per test :256 megabytes input: standard inp ...

  2. SQL存储过程删除数据库日志文件的方法

    --日志文件收缩至多少M DECLARE @DBLogSise AS INT SET @DBLogSise=0 --查询出数据库对应的日志文件名称 DECLARE @strDBName AS NVAR ...

  3. cv_prj2

    Computer Vision Project 2 – Harris Corner Detector 姓名: 王兴路 学号: 3140102282 指导老师: 宋明黎 2016-12-16 19:30 ...

  4. EasyUI detailview 使用心得

    view: detailview, detailFormatter: function (rowIndex, rowData) { return "<div class='easyui ...

  5. smarty模板中获得循环次数

    在smarty中可以有两种写法来获得循环次数(当然lz只会这两种:>,要是有大神会有其他的,欢迎补充) 写法一: {section name=loop loop=3} {$smarty.loop ...

  6. Java学习笔记 06 数字格式化及数学运算

    一.数字格式化 DecimalFormat类 >>DecimalFormat是NumberFormat的子类,用于格式化十进制数,可以将一些数字格式化为整数.浮点数.百分数等.通过使用该类 ...

  7. Python操控mysql数据库

    导入库——MySQLdb 1.链接MySQL conn=MySQL.connect(host=',port=3306) 此处主机用ip地址,不能使用'localhost',不然会显示链接错误. 2.选 ...

  8. 如何删除选中的checkbox

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. Celery Running Environment

    After running celery in my machine, I got this: Running a worker with superuser privileges when the ...

  10. oracle中用户删除不了,ORA-01940提示 “无法删除当前已连接用户”

    Oracle删除用户的提示无法删除当前已连接用户两种解决方法如下: 1.先锁定用户.然后查询进程号,最后删除对应的进程.在删除对应的用户 SQL>alter user XXX account l ...