為什么要使用LayoutAnimtion???
在我們平常的開發(fā)中,對于普通需求,經(jīng)常會需要做一些簡單的位移,淡入淡出等動畫禾乘,而對于這種頻繁的動畫來說,使用Animated來做虽缕,雖然也是一個不錯的選擇始藕,但是Animated在使用的過程中,需要更多的代碼量氮趋,從定義變量伍派,啟動動畫,結(jié)束剩胁,等等流程都要手動控制诉植。如何高效快速地給App添加動畫,也是一個比較廣泛的需求昵观。這就是我們使用LayoutAnimation的原因晾腔,快速舌稀,高效,相比Animated灼擂,雖然對于動畫的控制減弱了壁查,但是同時也獲得了更高的開發(fā)效率。
和Animated有什么區(qū)別??
上面說了LayoutAnimation對比Animated的優(yōu)勢剔应,下面來更詳細(xì)的對比一下兩種方式在平常使用中的差異
首先是Animated(代碼取自官方文檔睡腿,并做了一些修改)
// part 1: 定義fadeAnim變量
state = {
fadeAnim: new Animated.Value(0)
}
// part 2: 在某個時機(jī)啟動動畫(這個例子中我們在didMount生命周期中啟動)
componentDidMount() {
Animated.timing(
this.state.fadeAnim,
{
toValue: 1,
duration: 10000,
}
).start();
}
// part 3: 在render中,使用Animated提供的Animated.View實現(xiàn)動畫
render() {
let { fadeAnim } = this.state;
return (
<Animated.View
style={{
opacity: fadeAnim,
}}
>
{this.props.children}
</Animated.View>
);
}
下面是LayoutAnimation
// part 1: 使用普通的state來定義變量
state = {
bottom: 0
}
// part 2:
// 此處假設(shè)我們在某個View的style中峻贮,使用了this.state.bottom這個變量作為bottom的值
// 是的席怪,只需要添加一行代碼,你的View就有了動畫月洛!
LayoutAnimation.spring();
this.setState({ bottom: 20 });
通過上面的代碼何恶,我們可以很直觀的發(fā)現(xiàn)LayoutAnimation有多方便,我們可以使用這個api以非常低的代價嚼黔,使我們的App加入動畫??
快速上手???♀?
React Native LayoutAnimation api提供了三個可以直接使用的api,分別是easeInEaseOut, linear, spring
LayoutAnimation.easeInEaseOut()
LayoutAnimation.linear()
LayoutAnimation.spring()
使用方式和上面的例子相同惜辑,只要在相應(yīng)的setState之前調(diào)用下面三個API其中之一唬涧,在UI更新的時候,React Native就會自動讓UI實現(xiàn)相應(yīng)的動畫效果盛撑。
進(jìn)階 - 自定義animation????
為了自定義animation碎节,我們就需要稍微深入的了解一下LayoutAnimation提供了哪些API了,首先抵卫,我們來看一下源碼中接口的定義吧
/**
* 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
其實最主要的方法只有configureNext狮荔,create只是一個幫助創(chuàng)建配置的方法
使用configureNext
LayoutAnimation.configureNext(
config: LayoutAnimationConfig, // 提供一個動畫的配置
onAnimationDidEnd?: Function, // 動畫結(jié)束的回調(diào),可以為空
)
從configureNext接口的定義中我們可以看到介粘,使用很簡單殖氏,提供一個LayoutAnimationConfig就可以了,那么這個LayoutAnimationConfig是什么呢
type LayoutAnimationConfig = $ReadOnly<{|
duration: number,
create?: AnimationConfig,
update?: AnimationConfig,
delete?: AnimationConfig,
|}>;
再次從定義中我們發(fā)現(xiàn)姻采,這個config就是一個object雅采,我們可以使用之前提到的create方法來快速生成它,下面是完整的使用例子
LayouteAnimation.configureNext(
LayoutAnimation.create(
// 動畫的時長
200,
// 動畫的類型慨亲, 例如linear婚瓜,spring,easeIn
LayouteAnimation.Types.linear,
// 動畫在哪些地方生效刑棵,scaleX就是在X軸生效
LayouteAnimation.Properties.scaleX
)
)
這樣巴刻,我們就完全實現(xiàn)了LayoutAnimation動畫的自定義了。更多的配置選項可以在源碼中發(fā)現(xiàn)!