在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属性,有一个缩放的效果。