1. 程式人生 > >React Native LayoutAnimation動畫

React Native LayoutAnimation動畫

在React Native中,LayoutAnimation用於在頁面佈局發生改變時,新增動畫效果。
LayoutAnimation使用簡單,要實現動畫效果只需要在setState()前新增LayoutAnimation動畫方法:

//新增一張圖片
    _addImg() {
        //LayoutAnimation.easeInEaseOut();//在setState()前,新增LayoutAnimation動畫方法
        this.setState({views: [...this.state.views, {}]});//往陣列中加入一個空物件
    }

    //移除最後一張圖片
_removeImg() { //LayoutAnimation.easeInEaseOut();//在setState()前,新增LayoutAnimation動畫方法 this.setState({views: this.state.views.slice(0, -1)});//移除views陣列中最後一個物件 }

或統一寫在componentWillUpdate()方法中,每當頁面中元素狀態改變的時候都會呼叫這個方法。

//佈局更新時執行
    componentWillUpdate() {
        LayoutAnimation.easeInEaseOut
();//每次元件更新前,執行LayoutAnimation動畫 }

LayoutAnimation支援的動畫型別:

  • caseInEaseOut
  • linear
  • spring

我們也可以自定義動畫效果:

//自定義動畫
var CustomLayoutAnimation={
    duration:800,//動畫執行的時間
    create:{//佈局建立時的動畫
        type:LayoutAnimation.Types.spring,//動畫型別(主要涉及:spring,linear,easeInEaseOut,easeIn,easeOut,keyboard)
        property:LayoutAnimation.
Properties.scaleXY,//動畫作用的元素屬性(主要涉及:opacity,scaleXY) }, update:{//佈局更新時的動畫 type:LayoutAnimation.Types.linear,//動畫型別 property:LayoutAnimation.Properties.opacity,//動畫作用的元素屬性 } };

通過LayoutAnimation.configureNext()方法,我們就可以執行我們自定義的動畫

//佈局更新時執行
    componentWillUpdate() {  LayoutAnimation.configureNext(CustomLayoutAnimation);//執行自定義LayoutAnimation動畫
    }

完整程式碼如下:

/**
 * Created by gyg on 2017/5/17.
 */
'use strict'
import React, {Component} from 'react';
import {
    StyleSheet,
    View,
    Image,
    Text,
    TouchableHighlight,
    LayoutAnimation,
    Platform,
    UIManager,
}from 'react-native';

//自定義動畫
var CustomLayoutAnimation={
    duration:800,//動畫執行的時間 毫秒
    create:{//佈局建立時的動畫
        type:LayoutAnimation.Types.spring,//動畫型別(主要涉及:spring,linear,easeInEaseOut,easeIn,easeOut,keyboard)
        property:LayoutAnimation.Properties.scaleXY,//動畫作用的元素屬性(主要涉及:opacity,scaleXY)
    },
    update:{//佈局更新時的動畫
        type:LayoutAnimation.Types.linear,//動畫型別
        property:LayoutAnimation.Properties.opacity,//動畫作用的元素屬性
    }
};

export default class LayoutAnimationDemo extends Component {

    // 構造
    constructor(props) {
        super(props);
        if (Platform.OS == 'android') {//android平臺需要開啟允許LayoutAnimation ios預設開啟
            UIManager.setLayoutAnimationEnabledExperimental && UIManager.setLayoutAnimationEnabledExperimental(true);
        }
        // 初始狀態
        this.state = {
            views: []
        };
    }

    //佈局更新時執行
    componentWillUpdate() {
        LayoutAnimation.easeInEaseOut();//每次元件更新前,執行LayoutAnimation動畫
        //LayoutAnimation.configureNext(CustomLayoutAnimation);//執行自定義LayoutAnimation動畫
    }

    //新增一張圖片
    _addImg() {
        //LayoutAnimation.easeInEaseOut();//在setState()前,新增LayoutAnimation動畫方法
        this.setState({views: [...this.state.views, {}]});//往陣列中加入一個空物件
    }

    //移除最後一張圖片
    _removeImg() {
        //LayoutAnimation.easeInEaseOut();//在setState()前,新增LayoutAnimation動畫方法
        this.setState({views: this.state.views.slice(0, -1)});//移除views陣列中最後一個物件
    }

    render() {
        const views = this.state.views.map((view, i)=> {
            return (
                <Image key={i} source={require('../../res/girl.jpg')} style={styles.image}
                />
            );
        });//將this.state.views陣列中的每個元素對映成一個<Image/>元件
        return (
            <View style={styles.container}>
                <View style={styles.buttonLinear}>
                    <TouchableHighlight style={styles.button} underlayColor={"#eeeeee"}
                                        onPress={this._addImg.bind(this)}>
                        <Text style={styles.buttonText}>add</Text>
                    </TouchableHighlight>
                    <TouchableHighlight style={styles.button} underlayColor={"#eeeeee"}
                                        onPress={this._removeImg.bind(this)}>
                        <Text style={styles.buttonText}>remove</Text>
                    </TouchableHighlight>
                </View>
                <View style={styles.viewContainer}>
                    {views}
                </View>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: 'white',
    },
    buttonLinear: {
        flexDirection: 'row',
        marginTop: 20,
        justifyContent: 'space-around'
    },
    button: {
        borderRadius: 5,
        backgroundColor: "#eeeeee",
        paddingLeft: 20,
        paddingRight: 20,
        paddingTop: 10,
        paddingBottom: 10,
    },
    buttonText: {
        fontSize: 16,
    },
    image: {
        width: 50,
        height: 50,
        margin: 1,
    },
    viewContainer: {
        flexDirection: 'row',
        flexWrap: 'wrap',
        marginTop: 30,
    }
})

系統動畫效果:
這裡寫圖片描述
可以看出,原生動畫是改變的元素的opacity屬性,有一個淡入淡出的效果
自定義動畫效果:
這裡寫圖片描述
自定義動畫改變的是元素的scaleXY屬性,有一個縮放的效果。