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: 1,
  duration: 500,
  useNativeDriver: true, // <-- Add this
}).start();

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

注意事项:
不是所有的东西都可以使用原生驱动,最主要的限制就是,你只能使用非布局的属性,比如transform或者opacity可以,而flexbox和位置属性不行,另外对于Animated.event,该方式只能工作于直接的事件而不是冒泡事件,这也就意味着,PanResponder不能使用但是scrollView的onScroll方法可以。

虽然原生驱动很早就有了,但是却没有文档说明,主要是因为之前这个是一种实验性质的方式,所以如果想用的话,确保RN的版本在0.40以上。

猜你喜欢

转载自blog.csdn.net/zramals/article/details/78687615
今日推荐