慢牛系列四:好玩的React Native
在上次随笔(系列三)中,我试着用RN实现了一个Demo,感觉很不错,当时遇到的问题这篇文章里基本都解决了,比如导航动画问题,这篇文章里主要介绍RN的动画,学会动画以后,各种小创意都可以实现了^^
下面是我自己做的效果:
1、列表项滑动显示操作按钮

2、列表行滑出

3、K线页面

4、转场动画

一、React Native动画
RN的动画实现类似Jquery和CSS3的动画实现,设定某一属性的输入和输出值,后台实现相关的动画计算,简化了动画的开发,下面是一段代码,可以直观感受下
class Playground extends React.Component {
constructor(props: any) {
super(props);
this.state = {
bounceValue: new Animated.Value(0), //设定初始值
};
}
render(): ReactElement {
return (
<Animated.Image // Base: Image, Text, View,这三个标签可以实现动画,必须是Animate.开头,普通的Image不能实现动画。
source={{uri: 'http://i.imgur.com/XMKOH81.jpg'}}
style={{
flex: 1,
transform: [ // `transform` 类似CSS3
{scale: this.state.bounceValue}, // 设置 `bounceValue` 给 `scale`,注意,这里要使用上面再state里创建的对象,不能重新实例一个对象赋值。
]
}}
/>
);
}
//UI渲染结束后执行该方法
componentDidMount() {
this.state.bounceValue.setValue(1.5); // 设定初始大小,使用的依旧是在state中创建的对象。
Animated.spring( // Base: spring, decay, timing,这个三个方法是三种动画,spring是类似弹簧的动画
this.state.bounceValue, // Animate `bounceValue`初始输入值
{
toValue: 0.8, // Animate to smaller size,动画目标值
friction: 1, // Bouncier spring,这个值类似设置弹簧的弹性。
}
).start(); // Start the animation,开始动画,start的参数是一个动画结束的callback。
}
}
RN动画的主要类库是Animated库,Animated库包括Value和ValueXY两个类型,Value是单值的动画,比较简单,就是某个属性值的改变,ValueXY是向量的动画,就是两个值的改变,参数X,Y是元素的坐标,根据XY的变化计算运动方向。目前支持动画的元素View, Text, and Image,用户可以自己创建动画元素,通过Animated.createAnimatedComponent来创建。
目前主要有三种动画实现:spring, decay, timing,
spring: 类似弹簧的实现,动画结束时会有个渐弱的摆动,上面的第一个和第二个动画就是用spring实现。friction: 数值越小,弹的越厉害,默认是7。tension: 动画的速度,默认是40。
decay: 动画的速度逐渐变慢,最后停止,类似上面的转场动画。velocity: 初始速度。deceleration: 减速度,默认是 0.997.
timing:线性动画,在设定时间内移动到终点,中间的动画可以设置,类似CSS3的animation-timing-functionduration: 动画持续时间 500.easing:类似css3的animation-timing-function,具体的实现在Easing模块里,是贝塞尔曲线(Bézier curve)的一个实现,这样使用 Easing.bezier(0.42, 0, 1, 1),参数设置参考这个网址:http://cubic-bezier.com/,默认的实现Easing.in和Easing.out和Easing.inOut。delay: 动画延迟开始时间。
组合动画:
如果需要同时执行多个动画,或者按顺序执行动画,就需要将动画组合执行,RN提供了parallel, sequence, stagger, delay, 这个四个方法组合动画,这些方法的参数都是一个动画的数组,使用起来很简单,parallel是并行执行, sequence是顺序执行, stagger是每个动画延迟一段时间执行, delay是延时,下面是代码示例:
Animated.sequence([ // spring to start and twirl after decay finishes
Animated.decay(position, { // coast to a stop
velocity: {x: gestureState.vx, y: gestureState.vy}, // velocity from gesture release
deceleration: 0.997,
}),
Animated.parallel([ // after decay, in parallel:
Animated.spring(position, {
toValue: {x: 0, y: 0} // return to start
}),
Animated.timing(twirl, { // and twirl
toValue: 360,
}),
]),
]).start(); // start the sequence group
关于RN动画更多内容参考:http://facebook.github.io/react-native/docs/animations.html#content
二、动画demo
我做了一个动画的demo,这里只是改变了元素的left属性,大家体验下:

/* @flow */
'use strict'; var React = require('react-native');
var Easing = require('Easing');
var {
TouchableWithoutFeedback,
StyleSheet,
View,
Image,
Text,
Animated,
Dimensions,
InteractionManager
} = React;
var SCREEN_WIDTH = Dimensions.get('window').width;
var Component = React.createClass({
getInitialState: function() {
return {
first:new Animated.Value(0),
second:new Animated.Value(0),
three:new Animated.Value(0)
};
},
reset:function (argument) {
this.state.first.setValue(0);
this.state.second.setValue(0);
this.state.three.setValue(0);
},
getAnimations:function (argument) {
return[
Animated.spring( // Base: spring, decay, timing
this.state.first, // Animate `bounceValue`
{
toValue: SCREEN_WIDTH-50, // Animate to smaller size
friction: 7,
tension:40 // Bouncier spring
}
),
Animated.decay( // Base: spring, decay, timing
this.state.second, // Animate `bounceValue`
{
//toValue: SCREEN_WIDTH-50, // Animate to smaller size
velocity: 1,
deceleration:0.997 // Bouncier spring
}
),
Animated.timing( // Base: spring, decay, timing
this.state.three, // Animate `bounceValue`
{
toValue: SCREEN_WIDTH-50, // Animate to smaller size
easing: Easing.inOut(Easing.ease),
delay:0 // Bouncier spring
}
)
];
},
onStagger:function (argument) {
this.reset();
Animated.stagger(150,this.getAnimations()).start();
},
onParallel:function (argument) {
this.reset();
Animated.parallel(this.getAnimations()).start();
},
onSequence:function (argument) {
this.reset();
Animated.sequence(this.getAnimations()).start();
},
onAll:function (argument) {
var me=this;
this.reset();
Animated.sequence([
Animated.stagger(50,me.getAnimations()),
Animated.sequence([
Animated.spring( // Base: spring, decay, timing
this.state.first, // Animate `bounceValue`
{
toValue: 0, // Animate to smaller size
friction: 7,
tension:40 // Bouncier spring
}
),
Animated.decay( // Base: spring, decay, timing
this.state.second, // Animate `bounceValue`
{
//toValue: SCREEN_WIDTH-50, // Animate to smaller size
velocity: -1,
deceleration:0.997 // Bouncier spring
}
),
Animated.timing( // Base: spring, decay, timing
this.state.three, // Animate `bounceValue`
{
toValue: 0, // Animate to smaller size
easing: Easing.bezier(.13,.93,.79,.07),
delay:0 // Bouncier spring
}
)
]),
Animated.parallel(me.getAnimations())
]).start();
},
render: function() {
return (
<View style={styles.container}>
<View style={{flex:1}}>
<Animated.View style={[styles.view,{top:50,left:this.state.first}]}><Text>spring</Text></Animated.View>
<Animated.View style={[styles.view,{top:150,left:this.state.second}]}><Text>decay</Text></Animated.View>
<Animated.View style={[styles.view,{top:250,left:this.state.three}]}><Text>timing</Text></Animated.View>
</View>
<View style={{flexDirection:'row',height:80,justifyContent :'center',alignItems: 'center'}}>
<TouchableWithoutFeedback onPress={this.onStagger}>
<View style={styles.btn}><Text>stagger</Text></View>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback onPress={this.onParallel}>
<View style={styles.btn}><Text>parallel</Text></View>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback onPress={this.onSequence}>
<View style={styles.btn}><Text>sequence</Text></View>
</TouchableWithoutFeedback>
<TouchableWithoutFeedback onPress={this.onAll}>
<View style={styles.btn}><Text>组合</Text></View>
</TouchableWithoutFeedback>
</View>
</View>
);
}
}); var styles = StyleSheet.create({
container:{
flex:1
},
view:{
position:'absolute',
backgroundColor:'red',
width:50,
height:50,
justifyContent :'center',
alignItems: 'center',
},
btn:{
width:100,
height:50,
backgroundColor:'red',
justifyContent :'center',
alignItems: 'center',
margin:5
}
}); module.exports = Component;
RN动画示例
三、性能优化
主要是在执行动画时,避免执行其他工作量比较大的代码,比如,最好不要一边渲染,一边执行动画,而是先执行动画,等动画执行结束后在渲染,可以setTimeout来延时执行渲染,最好是用官方推荐的做法,利用InteractionManager,下面是代码示例:
componentDidMount() {
InteractionManager.runAfterInteractions(() => {
this.setState({renderPlaceholderOnly: false});
});
}
InteractionManager.runAfterInteractions是在动画或者操作结束后执行,还有其他两种方法:
- requestAnimationFrame(): H5的标准,RN实现了它,下一帧渲染时执行,更好的利用浏览器的刷新频率,避免丢帧。
- setImmediate/setTimeout(): 定时执行,有可能影响动画的流畅度。
另外,这个项目里用了MPAndroidChart组件,我对MPAndroidChart做了桥接,有想用的用户可以试试这个项目:
https://github.com/hongyin163/react-native-chart-android
如果有想体验React Native的用户,可以下载慢牛APP的APK体验:
关注慢牛的公众号:发送react,返回apk下载链接,apk大小8M,最好连接WiFi下载。

最后,欢迎园友提出好的想法,评论留名!谢谢!
慢牛系列四:好玩的React Native的更多相关文章
- React-Native(四):React Native之View学习
React Native实现以下布局效果:携html5(http://m.ctrip.com/html5/) 基于HelloWord修改项目代码: /** * Sample React Native ...
- React Native Android入门实战及深入源代码分析系列(2)——React Native源代码编译
本文为老曾原创.转载需注明出处:viewmode=contents">http://blog.csdn.net/minimicall?viewmode=contents 在上一节中,我 ...
- React Native入门指南
转载自:http://www.jianshu.com/p/b88944250b25 前言 React Native 诞生于 2015 年,名副其实的富二代,主要使命是为父出征,与 Apple 和 Go ...
- 写给移动开发者的 React Native 指南
本文原创版权归 简书 wingjay 所有,如有转载,请于文章篇头位置显示标注原创作者及出处,以示尊重! 作者:wingjay 出处:http://www.jianshu.com/p/b8894425 ...
- 一起来点React Native——你必须要会点FlexBox布局
一.FlexBox布局 1.1 FlexBox是什么意思呢? flexible(形容词):能够伸缩或者很容易变化,以适应外界条件的变化 box(名词):通用的矩形容器 1.2 什么是FlexBox布 ...
- React Native混合开发中必须要学会点FlexBox布局
在前面的案例中,界面的搭建都是采用CSS的布局,基于盒子模型,依赖 display属性 , position属性, float属性.但对于那些特殊布局非常不方便,比如,垂直居中. 一种全新的针对web ...
- 慢牛系列三:React Native实践
上次发布了我的慢牛股票APP之后,有园友反馈有点卡,这个APP是基于Sencha Touch + Cordova开发的,Sencha本身是一个比较重的框架,在Chrome里运行性能还是不错的,但是在A ...
- React Native 系列(四) -- 布局
前言 本系列是基于React Native版本号0.44.3写的.RN支持CSS中的布局属性,因此可以使用CSS布局属性,这里就不详细地讲解了,这篇文章的重点主要是讲述一下RN中的Flex布局. CS ...
- React Native 系列(四)
前言 本系列是基于React Native版本号0.44.3写的.RN支持CSS中的布局属性,因此可以使用CSS布局属性,这里就不详细地讲解了,这篇文章的重点主要是讲述一下RN中的Flex布局. CS ...
随机推荐
- 机器学习六--K-means聚类算法
机器学习六--K-means聚类算法 想想常见的分类算法有决策树.Logistic回归.SVM.贝叶斯等.分类作为一种监督学习方法,要求必须事先明确知道各个类别的信息,并且断言所有待分类项都有一个类别 ...
- [原]openstack-kilo--issue(五) neutron-agent服务实际是active的-但是显示为XXX
问题出现: 重启后出现了这样的情况: 查看详细的参数 查看数据库neutron 中对应的agents表.发现表中没有alive这个字段 这些服务的实际状态为active: ----1------● n ...
- cocos2d-x之悦动的小球
发现问题:update()函数不能用virtual前缀 主: bool HelloWorld::init() { if ( !LayerColor::initWithColor(Color4B(255 ...
- 第一次配置Android环境
配置Android环境,相信很多人都做过,而且网上的资料也一大堆,我就来分享一下我配置Android的心得吧! 第一步:下载好需要的文件:Android SDK.JDK.Eclipse.ADT ps: ...
- mysql table 最新更新时间
查看表的最后mysql修改时间 SELECT TABLE_NAME,UPDATE_TIME FROM information_schema.tables where TABLE_SCHEMA='d ...
- hdu 2196 Computer 树形dp模板题
Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- quick sort java version
import java.util.Random; public class test { public static void main(String[] args) { int[] arr= gen ...
- 【Android UI设计与开发】1.引导界面(一)ViewPager介绍和简单实现
1.ViewPager 实现效果图 2.ViewPager 实现功能 ViewPager类提供了多界面切换的新效果,新效果有如下特征: <1>当前显示一组界面中的其中一个界面: <2 ...
- Django项目中model增加了新字段怎样更新?
Django是不直接支持syncdb更新数据库的字段的,必须重新建立. 或者改一个表名新建一个表... 刚刚想出来一招: 自己在表上面先加一个字段,然后再在model上面改,貌似是可以的.
- Javascript中的对象和原型(3)
在Javascript中的对象和原型(二)中我们提到,用构造函数创建的对象里面,每个对象之间都是独立的,这样就会降低系统资源的利用率,解决这样问题,我们就要用到下面提到的原型对象. 一 原型对象 原型 ...