React Native Animated 动画之 加载中loading
用RN的Animated做一个简单的加载中动画
加载中 是APP中很常见的一种交互,自己也是刚入手React Native,加载列表的时候需要一个loading状态,那我们就开始吧。
首先撸一遍思路
- 首先,在ReactNative中要使我们的loading图标允许动画,我们可以使用
createAnimatedComponent()
创建的组件加载我们的图标,或者直接使用Animated下默认封装好了的:Animated.Image
Animated.ScrollView
Animated.Text
Animated.View - 然后动画方式是我们熟悉的 属性:
transform
,写法和CSS3少许不同 - 接着是旋转动画
rotate
的值,通过Animated
的方法不断更新
从文档开始
ReactNative-Animated文档 Animated
的主要相关方法有4个:
Animated.decay()
Animated.spring()
Animated.timing()
Animated.loop()
前两个分别是特定曲线(衰弱、反弹)效果,这里我使用timing
,便于自定义自己的动画效果。 timing
函数接受2个参数,第一个初始value,第二个是配置json,类似:
Animated.timing(
initValue, // 由new Animated.Value(0)创建
{
toValue: Number, // 动画到达值
delay: Number, // 延迟动画,默认 0
duration: Number, // initValue => toValue持续的时间,默认 500
easing: Function, // 动画曲线
useNativeDriver: Boolean, // 是否启用原生动画驱动,默认false
}
)
其中动画曲线函数可以参考 RN api-Easing
此时动画完成一半,只是从initValue
转到toValue
就结束了。要循环动画,这里有两种思路:
-
在
Animated.timing(...).start(callback)
动画执行完毕后的callback函数中再次调用此动画,类似let animation = Animated.timing(...); animation.start(animation.start)
使用
Animated.loop()
(本例)。关于loop方法:
大概意思就是:
其可接受2个参数:animation(可由上面3个方法创建);config(可选配置json:{iterations: Number, // 循环次数}
)。当useNativeDriver
设置为true
的时候,动画将不会阻塞页面UI、JS等线程。
还有一个注意点就是rotate
的值是一个字符串,并且有单位,而我们的初始值和终点值以及期间的值都是 Number
,所以这里会用到一个插值函数interpolate()
,上面的文档以及这篇 RN-动画animations 里有提到。demo会用到。
贴上一个简单的demo
import React, { Component } from 'react';
import {
View,
Text,
Image,
Animated, // 这两个都是要引入的
Easing,
} from 'react-native';
export default class Loading extends Component {
state = {
rotateVal: new Animated.Value(0),
}
componentDidMount(){ // 组件加载完成后启动动画
const animationLoading = Animated.timing(
this.state.rotateVal, // 初始值
{
toValue: 360, // 终点值
easing: Easing.linear, // 这里使用匀速曲线,详见RN-api-Easing
}
);
Animated.loop(animationLoading).start(); // 开始动画
setTimeout(Animated.loop(animationLoading).stop, 5000); // 5秒后停止动画,可用于任意时刻停止动画
}
render(){ // 渲染界面
return(
<View>
// 我项目中用字体图标,所以这里用.Text,也可以用.Image加载一张图片,然后样式属性中transform
<Animated.Text
style={{
textAlign: 'center',
fontSize: 34,
fontFamily: 'iconfont',
transform: [{ // 动画属性
rotate: this.state.rotateVal.interpolate({
inputRange: [0, 360],
outputRange: ['0deg', '360deg'],
})
}]
}}>
{'\ue6ae'}
</Animated.Text>
</View>
)
}
}
当然还有许多组合操作,可以慢慢尝试
上一篇: mac利用ichat实现人人桌面聊天功能
下一篇: 页面预加载loading动画,再载入内容