在咱們日常的開發中,對於普通需求,常常會須要作一些簡單的位移,淡入淡出等動畫,而對於這種頻繁的動畫來講,使用Animated來作,雖然也是一個不錯的選擇,可是Animated在使用的過程當中,須要更多的代碼量,從定義變量,啓動動畫,結束,等等流程都要手動控制。如何高效快速地給App添加動畫,也是一個比較普遍的需求。這就是咱們使用LayoutAnimation的緣由,快速,高效,相比Animated,雖然對於動畫的控制減弱了,可是同時也得到了更高的開發效率。react
上面說了LayoutAnimation對比Animated的優點,下面來更詳細的對比一下兩種方式在日常使用中的差別 首先是Animated(代碼取自官方文檔,並作了一些修改)git
// part 1: 定義fadeAnim變量
state = {
fadeAnim: new Animated.Value(0)
}
// part 2: 在某個時機啓動動畫(這個例子中咱們在didMount生命週期中啓動)
componentDidMount() {
Animated.timing(
this.state.fadeAnim,
{
toValue: 1,
duration: 10000,
}
).start();
}
// part 3: 在render中,使用Animated提供的Animated.View實現動畫
render() {
let { fadeAnim } = this.state;
return (
<Animated.View
style={{
opacity: fadeAnim,
}}
>
{this.props.children}
</Animated.View>
);
}
複製代碼
下面是LayoutAnimationgithub
// part 1: 使用普通的state來定義變量
state = {
bottom: 0
}
// part 2:
// 此處假設咱們在某個View的style中,使用了this.state.bottom這個變量做爲bottom的值
// 是的,只須要添加一行代碼,你的View就有了動畫!
LayoutAnimation.spring();
this.setState({ bottom: 20 });
複製代碼
經過上面的代碼,咱們能夠很直觀的發現LayoutAnimation有多方便,咱們可使用這個api以很是低的代價,使咱們的App加入動畫✌️spring
React Native LayoutAnimation api提供了三個能夠直接使用的api,分別是easeInEaseOut, linear, springreact-native
LayoutAnimation.easeInEaseOut()
LayoutAnimation.linear()
LayoutAnimation.spring()
複製代碼
使用方式和上面的例子相同,只要在相應的setState以前調用下面三個API其中之一,在UI更新的時候,React Native就會自動讓UI實現相應的動畫效果。api
爲了自定義animation,咱們就須要稍微深刻的瞭解一下LayoutAnimation提供了哪些API了,首先,咱們來看一下源碼中接口的定義吧bash
/**
* Automatically animates views to their new positions when the
* next layout happens.
*
* A common way to use this API is to call it before calling `setState`.
*
* Note that in order to get this to work on **Android** you need to set the following flags via `UIManager`:
*
* UIManager.setLayoutAnimationEnabledExperimental && UIManager.setLayoutAnimationEnabledExperimental(true);
*/
const LayoutAnimation = {
/**
* Schedules an animation to happen on the next layout.
*
* @param config Specifies animation properties:
*
* - `duration` in milliseconds
* - `create`, `AnimationConfig` for animating in new views
* - `update`, `AnimationConfig` for animating views that have been updated
*
* @param onAnimationDidEnd Called when the animation finished.
* Only supported on iOS.
* @param onError Called on error. Only supported on iOS.
*/
configureNext,
/**
* Helper for creating a config for `configureNext`.
*/
create,
Types: Object.freeze({
spring: 'spring',
linear: 'linear',
easeInEaseOut: 'easeInEaseOut',
easeIn: 'easeIn',
easeOut: 'easeOut',
keyboard: 'keyboard',
}),
Properties: Object.freeze({
opacity: 'opacity',
scaleX: 'scaleX',
scaleY: 'scaleY',
scaleXY: 'scaleXY',
}),
checkConfig(...args: Array<mixed>) {
console.error('LayoutAnimation.checkConfig(...) has been disabled.');
},
Presets,
easeInEaseOut: (configureNext.bind(null, Presets.easeInEaseOut): (
onAnimationDidEnd?: any,
) => void),
linear: (configureNext.bind(null, Presets.linear): (
onAnimationDidEnd?: any,
) => void),
spring: (configureNext.bind(null, Presets.spring): (
onAnimationDidEnd?: any,
) => void),
};
複製代碼
其實最主要的方法只有configureNext,create只是一個幫助建立配置的方法app
LayoutAnimation.configureNext(
config: LayoutAnimationConfig, // 提供一個動畫的配置
onAnimationDidEnd?: Function, // 動畫結束的回調,能夠爲空
)
複製代碼
從configureNext接口的定義中咱們能夠看到,使用很簡單,提供一個LayoutAnimationConfig就能夠了,那麼這個LayoutAnimationConfig是什麼呢動畫
type LayoutAnimationConfig = $ReadOnly<{|
duration: number,
create?: AnimationConfig,
update?: AnimationConfig,
delete?: AnimationConfig,
|}>;
複製代碼
再次從定義中咱們發現,這個config就是一個object,咱們可使用以前提到的create方法來快速生成它,下面是完整的使用例子ui
LayouteAnimation.configureNext(
LayoutAnimation.create(
// 動畫的時長
200,
// 動畫的類型, 例如linear,spring,easeIn
LayouteAnimation.Types.linear,
// 動畫在哪些地方生效,scaleX就是在X軸生效
LayouteAnimation.Properties.scaleX
)
)
複製代碼
這樣,咱們就徹底實現了LayoutAnimation動畫的自定義了。更多的配置選項能夠在源碼中發現!