天天看點

react-native動畫原生驅動

react-native動畫原生驅動

一、說明

在RN中建立動畫一般使用Animated元件,定義動畫元件,定義動畫屬性,然後使用Animated提供的幾種方法讓動畫生成。

首先,使用Animated元件生成動畫的流程圖如下:

  1. JS端:動畫驅動在每一幀上執行requestanimationframe方法,更新value,驅動不斷的使用新的value計算動畫視圖。
  2. JS端:計算內插補點,并且傳遞給綁定的view
  3. JS端:使用setNativeProps來更新View
  4. JS到原生橋接
  5. 原生端:View更新

是以可以看到,大多數工作都在JS端,如果JS端被阻塞,動畫将會跳幀,并且每幀都需要JS傳遞到原生端去更新。

而使用RN提供給動畫的原生驅動方式,則可以将上面所有步驟都移交至native端,當Animated元件産生動畫節點圖之後,在動畫開始時,可以進行序列化,并傳遞到native直接執行,這樣就省去了向JS端callback的過程,而原生端隻關心在UI線程的每一幀,并直接更新。

基于此,使用原生驅動的動畫流程将變為:

1. 原生端:原生動畫驅動使用CADisplayLink或者android.view.Choreographer去執行每一幀,計算并更新動畫視圖得到的新值。

2. 原生端:內插補點計算并被傳遞給綁定的原生view

3. 原生端:UIView或者android.view更新

如此,沒有更多的JS線程,沒有更多的橋接,也就意味着更快的動畫效果。

二、在APP裡使用:

在Animated動畫設定中,添加useNativeDriver字段,并設為true,注意,如果使用了useNativeDriver字段來做原生驅動,那麼做原生驅動屬性的動畫都要使用原生驅動,否則會報錯。

原生驅動也可以與Animated.event方式一同作用,

例如:

Animated.timing(this.state.animatedValue, {
  toValue: ,
  duration: ,
  useNativeDriver: true, // <-- Add this
}).start();

<ScrollView
  scrollEventThrottle={}
  onScroll={Animated.event(
    [{ nativeEvent: { contentOffset: { y: this.state.animatedValue } } }]
  )}
>
  {content}
</ScrollView>
           

注意事項:

不是所有的東西都可以使用原生驅動,最主要的限制就是,你隻能使用非布局的屬性,比如transform或者opacity可以,而flexbox和位置屬性不行,另外對于Animated.event,該方式隻能工作于直接的事件而不是冒泡事件,這也就意味着,PanResponder不能使用但是scrollView的onScroll方法可以。

雖然原生驅動很早就有了,但是卻沒有文檔說明,主要是因為之前這個是一種實驗性質的方式,是以如果想用的話,確定RN的版本在0.40以上。

繼續閱讀