美文网首页
RN中实现类似Android中的帧动画及坑

RN中实现类似Android中的帧动画及坑

作者: 咸鱼Jay | 来源:发表于2018-11-22 14:02 被阅读128次

一、前言

在Android中实现帧动画很简单,定义一个animation-list就可以直接使用了,例如:

<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false" >
    <item
        android:drawable="@drawable/custom_clock_time_01"
        android:duration="1000">
    </item>
    <item
        android:drawable="@drawable/custom_clock_time_02"
        android:duration="1000">
    </item>
    <item
        android:drawable="@drawable/custom_clock_time_03"
        android:duration="1000">
    </item>
    <item
        android:drawable="@drawable/custom_clock_time_04"
        android:duration="1000">
    </item>

二、实现

但是在RN中应该是没有这种简单的方法吧,不过也可以实现类似的效果,原理就是定义一个数组把帧动画需要的那些图片放入数组汇总,然后使用一个定时器setInterval不断的展示这几张图片,就可以了。

实现CockView组件

import React, {Component} from 'react';
import {
    Platform,
    StyleSheet,
    Text,
    View,
    Image
} from 'react-native';

var LoadingImgs = [
    require('./img/custom_clock_time_01.png'),
    require('./img/custom_clock_time_02.png'),
    require('./img/custom_clock_time_03.png'),
    require('./img/custom_clock_time_04.png'),
];

export default class CockView extends Component {
    //设置默认属性
    static defaultProps = {
        time: 60
    }

    constructor(props) {
        super(props);
        console.log("constructor==")
        this.state = {
            loadImgIndex: 0,
            time: props.time
        }
    }

    componentDidMount() {
        if (this.timer === undefined) {
            this.timer = setInterval(() => {
                let i = this.state.loadImgIndex + 1;
                i = i % LoadingImgs.length;
                this.setState({
                    loadImgIndex: i,
                    time: this.state.time - 1
                })
                if (this.state.time === 0) {
                    clearInterval(this.timer);
                }
                console.log("i==",i)
            }, 1000);
        }
    }

    componentWillUnmount() {
        this.timer && clearInterval(this.timer);
    }

    render() {
        return (
            <View style={{
                justifyContent: 'center',
                alignItems: 'center',
                flexDirection: 'row'
            }}>
                <View style={{marginLeft: 20}}>
                    <Text style={{fontSize: 30}}>{this.state.time} 秒</Text>
                </View>
            </View>
        )
    }
}

最后在其他地方使用这个组件就可以了, time是指定倒计时的时间

<CockView time={10}/>

三、问题

但是有个小bug,就是刚进入界面后,第一次循环,图片会闪烁,这是怎么回事呢?这个问题纠结了我好久,无意之间我直接使用Image控件一个一个加载每个图片,他就不会闪烁了,

render() {
        return (
            <View style={{
                justifyContent: 'center',
                alignItems: 'center',
            }}>
                <Image style={{width: 80, height: 80}} 
                    source={require('./img/custom_clock_time_01.png')} />
                <Image style={{width: 80, height: 80}}
                    source={require('./img/custom_clock_time_02.png')} />
                <Image style={{width: 80, height: 80}}
                    source={require('./img/custom_clock_time_03.png')} />
                <Image style={{width: 80, height: 80}}
                source={require('./img/custom_clock_time_04.png')} />
                <Image style={{width: 80, height: 80}}
                       source={LoadingImgs[this.state.loadImgIndex]} />
                <View style={{marginLeft: 20}}>
                    <Text style={{fontSize: 30}}>{this.state.time} 秒</Text>
                </View>
            </View>
        )
    }

从这我估计是第一次循环的时候,这四张都还没有缓存,所有有闪烁现象。

问题找到了,但是我页面中不可能把这四张都显示出来吧,有没有像Android中,只加载控件却不显示的方法呢?经过我多方查找貌似没有。难道这个没有问题了?好在我突然想到加载这四张图片,但是把这个Image的宽高都设置为0试一试,果然可以了

render() {
        return (
            <View style={{
                justifyContent: 'center',
                alignItems: 'center',
                flexDirection: 'row'
            }}>
                <Image style={{width: 0, height: 0}} 
                    source={require('./img/custom_clock_time_01.png')} />
                <Image style={{width: 0, height: 0}}
                    source={require('./img/custom_clock_time_02.png')} />
                <Image style={{width: 0, height: 0}}
                    source={require('./img/custom_clock_time_03.png')} />
                <Image style={{width: 0, height: 0}}
                source={require('./img/custom_clock_time_04.png')} />
                <Image style={{width: 80, height: 80}}
                       source={LoadingImgs[this.state.loadImgIndex]} />
                <View style={{marginLeft: 20}}>
                    <Text style={{fontSize: 30}}>{this.state.time} 秒</Text>
                </View>
            </View>
        )
    }

哈哈,虽然有点投机取巧,先这么用吧!

源代码地址

相关文章

  • RN中实现类似Android中的帧动画及坑

    一、前言 在Android中实现帧动画很简单,定义一个animation-list就可以直接使用了,例如: 二、实...

  • Android 动画

    Android中动画分为三种: 逐帧动画 补间动画 属性动画 逐帧动画 逐帧动画类似于gif或是电影的原理,通过将...

  • Android几种动画的总结(逐帧动画、补间动画)

    逐帧动画 逐帧动画也叫 Drawable Animation,是最简单最直观的动画效果。 在Android 中实现...

  • 第六单元

    一、android中的动画 动画分类: 1、帧动画2、补间动画3、属性动画 二、帧动画 类似于电影,一张张图片连续...

  • Android 动画锦集

    Android 动画可分为逐帧动画、补间动画、属性动画。使用传统的逐帧动画、补间动画可以实现 Android 基本...

  • android动画使用大全

    android中主要有三种方式来实现动画,补间动画、帧动画、属性动画。 1.补间动画(tween Animatio...

  • 属性动画详解

    1. 动画分类 Android 中动画分为 3 种:View 动画(视图动画)、帧动画、属性动画。 (1)帧动画:...

  • Android动画目录

    Android中的动画分类 Animation(动画):View Animation(视图动画):帧动画(Fram...

  • Android 动画总结

    Android 中的动画可以分为以下几类: 逐帧动画 补间动画 属性动画 一、逐帧动画 逐帧动画的原理就是让一系列...

  • 安卓动画

    Android 中的动画可以分为以下几类: 逐帧动画 补间动画 属性动画 1、逐帧动画 逐帧动画的原理就是让一系列...

网友评论

      本文标题:RN中实现类似Android中的帧动画及坑

      本文链接:https://www.haomeiwen.com/subject/emxlqqtx.html