在移动开发中,动画是提高用户体验不可缺少的一个元素。在React Native中,动画API提供了一些现成的组件:Animated.View,Animated.Text和Animated.Image默认支持动画。动画API会调用iOS或者Android的本地代码来完成这些组件的位移、大小等动画。

在React Native中,Animated创建过程如下:

  1. 创建Animated.Value,设置初始值,比如一个视图的opacity属性,最开始设置Animated.Value(0),来表示动画的开始时候,视图是全透明的。
  2. AnimatedValue绑定到Style的可动画属性,比如透明度,{opacity: this.state.fadeAnim}
  3. 使用Animated.timing来创建自动的动画,或者使用Animated.event来根据手势,触摸,Scroll的动态更新动画的状态
  4. 调用Animated.timeing.start()开始动画

Animated简介

大多数情况下,在 React Native 中创建动画是推荐使用 Animated API 的,其提供了三个主要的方法用于创建动画:

  1. Animated.timing() – 推动一个值按照一个过渡曲线而随时间变化。Easing 模块定义了很多缓冲曲线函数。
  2. Animated.decay() – 推动一个值以一个初始的速度和一个衰减系数逐渐变为0。
  3. Animated.spring() – 产生一个基于 Rebound 和 Origami 实现的Spring动画。它会在 
    toValue 值更新的同时跟踪当前的速度状态,以确保动画连贯。

除了这三个创建动画的方法,对于每个独立的方法都有三种调用该动画的方式:

  1. Animated.parallel() –同时开始一个动画数组里的全部动画。默认情况下,如果有任何一个动画停止了,其余的也会被停止。你可以通过stopTogether 选项来改变这个效果。
  2. Animated.sequence() –按顺序执行一个动画数组里的动画,等待一个完成后再执行下一个。如果当前的动画被中止,后面的动画则不会继续执行。
  3. Animated.stagger() – 一个动画数组,里面的动画有可能会同时执行(重叠),不过会以指定的延迟来开始。

Animated.timing()

使用 Animated.timing 创建的旋转动画。Animated.timing()的基本使用方法如下:

Animated.timing(someValue,{toValue: number,duration: number,easing: easingFunction,delay: number}
)

Easing 也是用React Native创建动画的载体,它允许我们使用已经定义好的各种缓冲函数,例如:linear, ease, quad, cubic, sin, elastic, bounce, back, bezier, in, out, inout 。由于有直线运动,我们将使用 linear。 
接下来,需要在构造函数中初始化一个带动画属性的值用于旋转动画的初始值:

constructor () {super()this.spinValue = new Animated.Value(0)
}

我们使用 Animated.Value声明了一个 spinValue 变量,并传了一个 0 作为初始值。然后创建了一个名为 spin 的方法,并在 componentDidMount 中调用它,目的是在 app 加载之后运行动画。

componentDidMount () {this.spin()
}
spin () {this.spinValue.setValue(0)Animated.timing(this.spinValue,{toValue: 1,duration: 4000,easing: Easing.linear}).start(() => this.spin())
}

现在方法已经创建好了,接下来就是在UI中渲染动画了。

render () {const spin = this.spinValue.interpolate({inputRange: [0, 1],outputRange: ['0deg', '360deg']})return (<View style={styles.container}><Animated.Imagestyle={{width: 227,height: 200,transform: [{rotate: spin}] }}source={{uri: 'https://s3.amazonaws.com/media-p.slid.es/uploads/alexanderfarennikov/images/1198519/reactjs.png'}}/></View>)
}

实现效果: 

完整代码:

/*** Sample React Native App* https://github.com/facebook/react-native* @flow*/import React, {Component} from 'react';
import {AppRegistry,StyleSheet,Text,Animated,TouchableOpacity,Easing,View
} from 'react-native';class AnimationRotateScene extends Component {constructor(props) {super(props);this.spinValue = new Animated.Value(0)}componentDidMount () {this.spin()}spin () {this.spinValue.setValue(0)Animated.timing(this.spinValue,{toValue: 1,duration: 4000,easing: Easing.linear}).start(() => this.spin())}render() {constspin = this.spinValue.interpolate({inputRange: [0, 1],outputRange: ['0deg', '360deg']})return (<View style={styles.container}><Animated.Imagestyle={{width: 227,height: 200,transform: [{rotate: spin}] }}source={{uri: 'https://s3.amazonaws.com/media-p.slid.es/uploads/alexanderfarennikov/images/1198519/reactjs.png'}}/><TouchableOpacity onPress={() => this.spin()} style={styles.button}><Text>启动动画</Text></TouchableOpacity></View>);}
}const styles = StyleSheet.create({container: {flex: 1,marginTop: 20,justifyContent: 'center',alignItems: 'center',},button: {marginTop: 20,backgroundColor:'#808080',height:35,width:140,borderRadius:5,justifyContent: 'center',alignItems: 'center',},
});export default AnimationRotateScene;
  • Animated.spring()

使用 Animated.spring() 方法创建一个放大缩小的动画。 

Animated.spring() 方法使用:

Animated.spring(someValue,{toValue: number,friction: number}
)

如上图所示,我们要使用Animated.spring()创建一个放大缩小的动画效果。 
在构造函数中,创建一个 springValue 变量,初始化其值为0.3。

constructor () {super()this.springValue = new Animated.Value(0.3)
}

然后,删除 animated 方法和componentDidMount方法,创建一个新的 spring 方法。

spring () {this.springValue.setValue(0.3)Animated.spring(this.springValue,{toValue: 1,friction: 1}).start()
}

然后我们给View的button添加一个点击事件,出发上面的spring动画。

<View style={styles.container}><Textstyle={{marginBottom: 100}}onPress={this.spring.bind(this)}>Spring</Text><Animated.Imagestyle={{ width: 227, height: 200, transform: [{scale: this.springValue}] }}source={{uri: 'https://s3.amazonaws.com/media-p.slid.es/uploads/alexanderfarennikov/images/1198519/reactjs.png'}}/>
</View>

完整代码如下:

/*** Sample React Native App* https://github.com/facebook/react-native* @flow*/import React, {Component} from 'react';
import {AppRegistry,StyleSheet,Text,Animated,TouchableOpacity,Easing,View
} from 'react-native';class AnimationRotateScene extends Component {constructor(props) {super(props);this.spinValue = new Animated.Value(0)}componentDidMount () {this.spin()}spin () {this.spinValue.setValue(0)Animated.timing(this.spinValue,{toValue: 1,duration: 4000,easing: Easing.linear}).start(() => this.spin())}render() {constspin = this.spinValue.interpolate({inputRange: [0, 1],outputRange: ['0deg', '360deg']})return (<View style={styles.container}><Animated.Imagestyle={{width: 227,height: 200,transform: [{rotate: spin}] }}source={{uri: 'https://s3.amazonaws.com/media-p.slid.es/uploads/alexanderfarennikov/images/1198519/reactjs.png'}}/><TouchableOpacity onPress={() => this.spin()} style={styles.button}><Text>启动动画</Text></TouchableOpacity></View>);}
}const styles = StyleSheet.create({container: {flex: 1,marginTop: 20,justifyContent: 'center',alignItems: 'center',},button: {marginTop: 20,backgroundColor:'#808080',height:35,width:140,borderRadius:5,justifyContent: 'center',alignItems: 'center',},
});export default AnimationRotateScene;

Animated.parallel()

Animated.parallel() 会同时开始一个动画数组里的全部动画。parallel()会接受一个动画数组,首先看一下api:

Animated.parallel(arrayOfAnimations)
// In use:
Animated.parallel([Animated.spring(animatedValue,{//config options}),Animated.timing(animatedValue2,{//config options})
])

所以,我们先创建一个动画数组,并初始化。

constructor () {super()this.animatedValue1 = new Animated.Value(0)this.animatedValue2 = new Animated.Value(0)this.animatedValue3 = new Animated.Value(0)
}

然后,创建一个 animate 方法并在 componendDidMount() 中调用它。

componentDidMount () {this.animate()
}
animate () {this.animatedValue1.setValue(0)this.animatedValue2.setValue(0)this.animatedValue3.setValue(0)const createAnimation = function (value, duration, easing, delay = 0) {return Animated.timing(value,{toValue: 1,duration,easing,delay})}Animated.parallel([createAnimation(this.animatedValue1, 2000, Easing.ease),createAnimation(this.animatedValue2, 1000, Easing.ease, 1000),createAnimation(this.animatedValue3, 1000, Easing.ease, 2000)        ]).start()
}

在 animate 方法中,我们将三个动画属性值重置为0。此外,还创建了一个 createAnimation 方法,该方法接受四个参数:value, duration, easing, delay(默认值是0),返回一个新的动画。

然后,调用 Animated.parallel(),并将三个使用 createAnimation 创建的动画作为参数传递给它。在 render 方法中,我们需要设置插值:

render () {const scaleText = this.animatedValue1.interpolate({inputRange: [0, 1],outputRange: [0.5, 2]})const spinText = this.animatedValue2.interpolate({inputRange: [0, 1],outputRange: ['0deg', '720deg']})const introButton = this.animatedValue3.interpolate({inputRange: [0, 1],outputRange: [-100, 400]})...
}

最后,我们用一个主 View 包裹三个 Animated.Views:

<View style={[styles.container]}><Animated.View style={{ transform: [{scale: scaleText}] }}><Text>Welcome</Text></Animated.View><Animated.Viewstyle={{ marginTop: 20, transform: [{rotate: spinText}] }}><Textstyle={{fontSize: 20}}>to the App!</Text></Animated.View><Animated.Viewstyle={{top: introButton, position: 'absolute'}}><TouchableHighlightonPress={this.animate.bind(this)}style={styles.button}><Textstyle={{color: 'white', fontSize: 20}}>Click Here To Start</Text></TouchableHighlight></Animated.View>
</View>

完整的代码如下:

/*** Sample React Native App* https://github.com/facebook/react-native* @flow 组动画*/import React, {Component} from 'react';
import {AppRegistry,StyleSheet,Text,Animated,TouchableOpacity,TouchableHighlight,Easing,View
} from 'react-native';class AnimationGroupScene extends Component {constructor() {super()this.animatedValue1 = new Animated.Value(0)this.animatedValue2 = new Animated.Value(0)this.animatedValue3 = new Animated.Value(0)}componentDidMount() {this.animate()}animate() {this.animatedValue1.setValue(0)this.animatedValue2.setValue(0)this.animatedValue3.setValue(0)const createAnimation = function (value, duration, easing, delay = 0) {return Animated.timing(value,{toValue: 1,duration,easing,delay})}Animated.parallel([createAnimation(this.animatedValue1, 2000, Easing.ease),createAnimation(this.animatedValue2, 1000, Easing.ease, 1000),createAnimation(this.animatedValue3, 1000, Easing.ease, 2000)]).start()}startAnimation() {this.state.currentAlpha = this.state.currentAlpha == 1.0 ? 0.0 : 1.0;Animated.timing(this.state.fadeAnim,{toValue: this.state.currentAlpha}).start();}render() {const scaleText = this.animatedValue1.interpolate({inputRange: [0, 1],outputRange: [0.5, 2]})const spinText = this.animatedValue2.interpolate({inputRange: [0, 1],outputRange: ['0deg', '720deg']})const introButton = this.animatedValue3.interpolate({inputRange: [0, 1],outputRange: [-100, 400]})return (<View style={styles.container}><Animated.Viewstyle={{transform: [{scale: scaleText}]}}><Text>Welcome</Text></Animated.View><Animated.Viewstyle={{marginTop: 20, transform: [{rotate: spinText}]}}><Textstyle={{fontSize: 20}}>to the App!</Text></Animated.View><Animated.Viewstyle={{top: introButton, position: 'absolute'}}><TouchableHighlightonPress={this.animate.bind(this)}style={styles.button}><Text>启动组动画</Text></TouchableHighlight></Animated.View></View>);}
}const styles = StyleSheet.create({container: {flex: 1,marginTop: 20,justifyContent: 'center',alignItems: 'center',},button: {marginTop: 20,backgroundColor: '#808080',height: 35,width: 140,borderRadius: 5,justifyContent: 'center',alignItems: 'center',},
});export default AnimationGroupScene;

示例使用说明



如图所示,我对动画的代码做了一个简单的整理,大家在使用的时候直接引入AnimationRoot文件即可。 
AnimationRoot文件内容如下:

/*** Sample React Native App* https://github.com/facebook/react-native* @flow*/import React, {Component} from 'react';
import { StackNavigator } from 'react-navigation';import AnimationIndex from './AnimationIndex';
import AnimationSpringScene from './AnimationSpringScene';//缩放动画
import AnimationRotateScene from './AnimationRotateScene';//旋转动画
import AnimationAlphaScene from './AnimationAlphaScene';//Alpha动画
import AnimationGroupScene from './AnimationGroupScene';//组动画
import AnimationFrameScene from './AnimationFrameScene';//帧动画const anim = StackNavigator({AnimationIndex: { screen: AnimationIndex },AnimationSpringScene: { screen: AnimationSpringScene },AnimationRotateScene: { screen: AnimationRotateScene },AnimationAlphaScene: { screen: AnimationAlphaScene },AnimationGroupScene: { screen: AnimationGroupScene },AnimationFrameScene: { screen: AnimationFrameScene },
});
export default anim;

最后是项目实现的最终结果图,代码地址动画源码

--------------------- 本文来自 code_xzh 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/xiangzhihong8/article/details/72783571?utm_source=copy

React Native动画Animated详解相关推荐

  1. [React Native] 动画 · Animated

    [React Native] 动画 · Animated 如果要在一个 React Native 应用中添加动画效果,首先考虑的就是官方提供的 Animated .通过定义输入和输出的动画状态值,调用 ...

  2. React Native通信机制详解

    http://blog.cnbang.net/tech/2698/ React Native是facebook刚开源的框架,可以用javascript直接开发原生APP,先不说这个框架后续是否能得到大 ...

  3. 19.React Native动画Animated效果三种动画类型二;

    目录 1.介绍 2.Animated.decay() 2.1方法 2.1.1value参数值 2.1.2config参数有以下这些属性: 2.2示例-执行缩放 2.2.1初始化缩放值 2.2.2绑定缩 ...

  4. React Native的Navigator详解

    欢迎Follow我的Github,博客会同步在Github的Blog仓库更新.也可以关注我的CSDN博客的React Native分类 Github地址:LeoMobileDeveloper 前言 除 ...

  5. React Native-9.React Native Touchable组件详解

    Touchable系列组件简介 RN中没有web中给元素绑定click事件的机制,但是在上一节中我们知道Text组件中我们可以绑定onPress事件来触发点击事件,为了像Text组件那样使得其它组件可 ...

  6. React Native 动画 ---Animated

    关于Animated动画,使用的时候组件不能直接写<Text></Text> 要写成 <Animated.Text></Animated.Text> 先 ...

  7. React Native Keyboard使用详解

    当我们点击输入框时,手机的软键盘会自动弹出,以便用户进行输入.但有时我们想在键盘弹出时对页面布局做个调整,或者在程序中使用代码收起这个软键盘,这些借助 React Native 框架提供的Keyboa ...

  8. react native FlatList 使用详解

    高性能的简单列表组件,支持下面这些常用的功能: 完全跨平台. 支持水平布局模式. 行组件显示或隐藏时可配置回调事件. 支持单独的头部组件. 支持单独的尾部组件. 支持自定义行间分隔线. 支持下拉刷新. ...

  9. React Native入门(十四)之动画(1)Animated详解

    前言 在APP的开发中,流畅合理的动画能大大提高用户体验,Android和iOS原生都有对应的动画系统,同样的在RN中也有用于创建动画的API,就是Animated.Animated库使得开发者可以非 ...

最新文章

  1. MySql报2006error错误的解决方法(数据过大)
  2. python代码大全o-Python简单I/O操作示例
  3. 百度 Serverless 架构揭秘与应用实践
  4. Android中的AnimationDrawable的使用
  5. Enterprise Solution 应用程序开发框架培训
  6. 从网络读取数据并动态的显示在ListView中
  7. linux 防arp 带宽,linux下防arp
  8. ShardingSphere Raw JDBC 主从示例
  9. Struts2+Spring+Hibernate搭建全解!
  10. 【Spring Cloud 系列】 二、Spring Cloud Eureka 的第一印象
  11. mysql 索引长度解释及不使用索引的一种特殊情况
  12. python循环语句for 循环十次_Python 循环 while,for语句
  13. MATLAB---画三角函数图像
  14. java 信鸽demo_腾讯信鸽推送Java服务端
  15. JavaScript 每日一题---LeetCode 122. 买卖股票的最佳时机 II
  16. AVS2的GB帧与s帧
  17. 东南亚电商平台 | Shopee 虾皮 入驻流程全解析
  18. C语言频率计程序,基于单片机的频率计的C语言源代码
  19. 【英语】-11月英语总结
  20. 04_JavaScript数据结构与算法(四)队列

热门文章

  1. Vue中使用防抖与截流
  2. Hex Editor Neo Ultimate系统要求
  3. ConvLSTM-AE for VAD (ICME2017-SIST)
  4. v-for 循环生成多个表单元素 给动态生成的表单元素绑定值并且添加校验规则
  5. 算法设计与分析之分治法
  6. 如何用python实现爬虫_如何用python实现网络爬虫原理?
  7. 求大神帮帮我,万分感谢,源码运行需要时间段,帮帮忙哈……
  8. 在线计算机容量单位换算,体积换算 | 容量计量单位转换器 —在线工具
  9. windows电脑打开jnlp文件设置
  10. 腾讯微信客服电话号码是多少呢/腾讯微信人工服务热线