在上次随笔(系列三)中,我试着用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的变化计算运动方向。目前支持动画的元素ViewText, and Image,用户可以自己创建动画元素,通过Animated.createAnimatedComponent来创建。

  目前主要有三种动画实现:spring, decay, timing,

  • spring: 类似弹簧的实现,动画结束时会有个渐弱的摆动,上面的第一个和第二个动画就是用spring实现。

    • friction: 数值越小,弹的越厉害,默认是7。
    • tension: 动画的速度,默认是40。
  • decay: 动画的速度逐渐变慢,最后停止,类似上面的转场动画。

    • velocity: 初始速度。
    • deceleration: 减速度,默认是 0.997.
  • timing:线性动画,在设定时间内移动到终点,中间的动画可以设置,类似CSS3的animation-timing-function

    • duration: 动画持续时间 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提供了parallelsequencestagger, 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的更多相关文章

  1. React-Native(四):React Native之View学习

    React Native实现以下布局效果:携html5(http://m.ctrip.com/html5/) 基于HelloWord修改项目代码: /** * Sample React Native ...

  2. React Native Android入门实战及深入源代码分析系列(2)——React Native源代码编译

    本文为老曾原创.转载需注明出处:viewmode=contents">http://blog.csdn.net/minimicall?viewmode=contents 在上一节中,我 ...

  3. React Native入门指南

    转载自:http://www.jianshu.com/p/b88944250b25 前言 React Native 诞生于 2015 年,名副其实的富二代,主要使命是为父出征,与 Apple 和 Go ...

  4. 写给移动开发者的 React Native 指南

    本文原创版权归 简书 wingjay 所有,如有转载,请于文章篇头位置显示标注原创作者及出处,以示尊重! 作者:wingjay 出处:http://www.jianshu.com/p/b8894425 ...

  5. 一起来点React Native——你必须要会点FlexBox布局

    一.FlexBox布局 1.1 FlexBox是什么意思呢? flexible(形容词):能够伸缩或者很容易变化,以适应外界条件的变化 box(名词):通用的矩形容器 1.2  什么是FlexBox布 ...

  6. React Native混合开发中必须要学会点FlexBox布局

    在前面的案例中,界面的搭建都是采用CSS的布局,基于盒子模型,依赖 display属性 , position属性, float属性.但对于那些特殊布局非常不方便,比如,垂直居中. 一种全新的针对web ...

  7. 慢牛系列三:React Native实践

    上次发布了我的慢牛股票APP之后,有园友反馈有点卡,这个APP是基于Sencha Touch + Cordova开发的,Sencha本身是一个比较重的框架,在Chrome里运行性能还是不错的,但是在A ...

  8. React Native 系列(四) -- 布局

    前言 本系列是基于React Native版本号0.44.3写的.RN支持CSS中的布局属性,因此可以使用CSS布局属性,这里就不详细地讲解了,这篇文章的重点主要是讲述一下RN中的Flex布局. CS ...

  9. React Native 系列(四)

    前言 本系列是基于React Native版本号0.44.3写的.RN支持CSS中的布局属性,因此可以使用CSS布局属性,这里就不详细地讲解了,这篇文章的重点主要是讲述一下RN中的Flex布局. CS ...

随机推荐

  1. 【php】使用phpdbg来调试php程序

    PHPDBG是一个PHP的SAPI模块,可以在不用修改代码和不影响性能的情况下控制PHP的运行环境 可以在PHP5.4和之上版本中使用.在PHP5.6和之上版本将内部集成 功能 单步调试 灵活的下断点 ...

  2. 【mysql】索引的优化

    写在前面的话 查询容易,优化不易,且写且珍惜 mysql结构 从MySQL逻辑架构来看,MySQL有三层架构,第一层连接,第二层查询解析.分析.优化.视图.缓存,第三层,存储引擎 MySQL有哪些索引 ...

  3. Tomcat常用的优化技巧

    (1)屏蔽DNS查询 Web应用程序可以通过Web容器提供的getRemoteHost()方法获得访问Web应用客户的IP地址和名称,但是这样会消耗Web容器的资源,并且还需要通过IP地址和DNS服务 ...

  4. Ajax详解及其案例分析------如何获得Ajax对象,使用Ajax对象发送GET和POST请求,校验用户名,POST和GET请求时的乱码处理,实现级联的下拉列表

    本节主要内容预览: 1 获得Ajax对象 2 使用Ajax对象发送GET请求 3 使用Ajax对象发送POST请求 4 使用Ajax校验用户名 5 POST请求时的乱码处理 6 GET请求时的乱码处理 ...

  5. powerdesigner设置表主键列为自动增长

    powerdesigner 版本12.5 创建表就不说了.下面开始介绍设置自动增长列. 1 在表视图的列上创建.双击表视图,打开table properties ———>columens ,双击 ...

  6. [转载] Android Metro风格的Launcher开发系列第一篇

    前言:从毕业到现在已经三年多了,回忆一下这三年基本上没有写过博客,总是觉得忙,没时间写,也觉得写博客没什么大用.但是看到很多大牛们都在写博客,分享自己的东西,所以嘛本着向大牛看齐,分享第一,记录第二的 ...

  7. 1维FDTD仿真

    FDTD基本原理是把麦克斯韦方程胡两个矢量旋度方程写成差分形式,利用数值方法求其解. 假设电磁场传播方向为x轴方向,电场只有z轴方法分量,磁场只有y轴方向分量.两个旋度方程可以写成下列形式 电场.磁场 ...

  8. Laxcus大数据管理系统2.0(5)- 第二章 数据组织

    第二章 数据组织 在数据的组织结构设计上,Laxcus严格遵循数据和数据描述分离的原则,这个理念与关系数据库完全一致.在此基础上,为了保证大规模数据存取和计算的需要,我们设计了大量新的数据处理技术.同 ...

  9. selenium如何操作cookies实现免登录

    执行接口测试或者某些自动化测试时,为了避免每次访问接口都需要登录操作,可以用访问接口时,把cookies信息传过去. 思路是先登录一次页面,获取到cookies信息,把cookies信息保存到本地文件 ...

  10. 【Android UI设计与开发】6.底部菜单栏(三)使用Fragment+PopupWindow仿QQ空间最新版底部菜单栏

    直接看栗子吧,效果基本实现,界面微调和弹窗的优化,去做的话会很耗时说,暂时就酱紫了.上传效果动态图太大了,直接手机截图的效果图如下: 至于代码的实现主要就是自定义的菜单栏,和用 PopupWindow ...