您的位置:首页 > Web前端 > React

React Native移动框架功能研究

2016-02-29 23:11 573 查看
ReactNative移动框架功能研究此篇只研究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}>
ReactNative
</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.
提供灵活的机制,方便自定义原生视图和模块。

四、
ReactNative
的功能

1.
样式

ReactNative
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
引擎中。

ReactNative
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
图片的内存问题


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: