[TOC]

概述

文章参考:https://github.com/dwqs/blog/issues/41

流畅、有意义的动画对于移动应用用户体验来说是非常重要的。现实生活中的物体在开始移动和停下来的时候都具有一定的惯性,我们在界面中也可以使用动画来实现契合物理规律的交互。
React Native 提供了两个互补的动画系统:用于创建精细的交互控制的动画Animated和用于全局的布局动画LayoutAnimation。

Animated

Animated使得开发者可以非常容易地实现各种各样的动画和交互方式,并且具备极高的性能。Animated旨在以声明的形式来定义动画的输入与输出,在其中建立一个可配置的变化函数,然后使用简单的start/stop方法来控制动画按顺序执行。 Animated仅封装了四个可以动画化的组件:View、Text、Image和ScrollView,不过你也可以使用Animated.createAnimatedComponent()来封装你自己的组件。下面是一个在加载时带有淡入动画效果的视图:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import React from 'react';
import { Animated, Text, View } from 'react-native';

class FadeInView extends React.Component {
state = {
fadeAnim: new Animated.Value(0), // 透明度初始值设为0
}

componentDidMount() {
Animated.timing( // 随时间变化而执行动画
this.state.fadeAnim, // 动画中的变量值
{
toValue: 1, // 透明度最终变为1,即完全不透明
duration: 10000, // 让动画持续一段时间
}
).start(); // 开始执行动画
}

render() {
let { fadeAnim } = this.state;

return (
<Animated.View // 使用专门的可动画化的View组件
style={{
...this.props.style,
opacity: fadeAnim, // 将透明度指定为动画变量值
}}
>
{this.props.children}
</Animated.View>
);
}
}

// 然后你就可以在组件中像使用`View`那样去使用`FadeInView`了
export default class App extends React.Component {
render() {
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
<FadeInView style={{width: 250, height: 50, backgroundColor: 'powderblue'}}>
<Text style={{fontSize: 28, textAlign: 'center', margin: 10}}>Fading in</Text>
</FadeInView>
</View>
)
}
}

Animated 库用于创建更精细的交互控制的动画,它使得开发者可以非常容易地实现各种各样的动画和交互方式,并且具备极高的性能。Animated 旨在以声明的形式来定义动画的输入与输出,在其中建立一个可配置的变化函数,然后使用简单的 start/stop 方法来控制动画按顺序执行。

Animated 提供了两种类型的值:

  • Animated.Value() 用于单个值。
  • Animated.ValueXY() 用于矢量值。

Animated.Value() 可以绑定到样式或是其他属性上,也可以进行插值运算。单个 Animated.Value() 可以用在任意多个属性上。

Animated 用于创建动画的主要方法:

Animated.timing():最常用的动画类型,使一个值按照一个过渡曲线而随时间变化。

Animated.spring():弹簧效果,基础的单次弹跳物理模型实现的 spring 动画。

Animated.decay():衰变效果,以一个初始的速度和一个衰减系数逐渐减慢变为0。

Animated 实现组合动画的主要方式:

  • Animated.parallel():同时开始一个动画数组里的全部动画。默认情况下,如果有任何一个动画停止了,其余的也会被停止。可以通过stopTogether 选项设置为 false 来取消这种关联。
  • Animated.sequence():按顺序执行一个动画数组里的动画,等待一个完成后再执行下一个。如果当前的动画被中止,后面的动画则不会继续执行。
  • Animated.stagger():一个动画数组,传入一个时间参数来设置队列动画间的延迟,即在前一个动画开始之后,隔一段指定时间才开始执行下一个动画里面的动画,并不关心前一个动画是否已经完成,所以有可能会出现同时执行(重叠)的情况。

Animated 封装了四个可以动画化的组件:

  1. Animated.View
  2. Animated.Text
  3. Animated.Image
  4. Animated.ScrollView

也可以使用 Animated.createAnimatedComponent() 来封装你自己的组件(用 Animated.View 包裹可以达到同样的效果)。

合成动画值:

  • Animated.add()
  • Animated.divide()
  • Animated.modulo()
  • Animated.multiply()

==可以使用加减乘除以及取余等运算来把两个动画值合成为一个新的动画值。==

插值函数:

interpolate():将输入值范围转换为输出值范围。
譬如:把0-1映射到0-10。

接下来,我们结合一个个的例子介绍它们的用法:

1. Animated.timing()

最常用的动画类型,使一个值按照一个过渡曲线而随时间变化,格式如下:

1
Animated.timing(animateValue, conf<Object>),conf参数格式: