React Native Animated 动画之 加载中loading

用RN的Animated做一个简单的加载中动画

加载中 是APP中很常见的一种交互,自己也是刚入手React Native,加载列表的时候需要一个loading状态,那我们就开始吧。

首先撸一遍思路

  1. 首先,在ReactNative中要使我们的loading图标允许动画,我们可以使用 createAnimatedComponent() 创建的组件加载我们的图标,或者直接使用Animated下默认封装好了的:
    Animated.Image
    Animated.ScrollView
    Animated.Text
    Animated.View
  2. 然后动画方式是我们熟悉的 属性:transform,写法和CSS3少许不同
  3. 接着是旋转动画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就结束了。要循环动画,这里有两种思路:

  1. Animated.timing(...).start(callback)动画执行完毕后的callback函数中再次调用此动画,类似

    let animation = Animated.timing(...);
    animation.start(animation.start)
  2. 使用Animated.loop()(本例)。关于loop方法:
    React Native Animated 动画之 加载中loading_第1张图片
    大概意思就是:
    其可接受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(
            
                // 我项目中用字体图标,所以这里用.Text,也可以用.Image加载一张图片,然后样式属性中transform
                'center',
                        fontSize: 34,
                        fontFamily: 'iconfont',
                        transform: [{ // 动画属性
                            rotate: this.state.rotateVal.interpolate({
                                inputRange: [0, 360],
                                outputRange: ['0deg', '360deg'],
                            })
                        }]
                    }}>
                    {'\ue6ae'}
                
            
        )
    }
}

当然还有许多组合操作,可以慢慢尝试

你可能感兴趣的:(React-native)