Motivation
在学习React Native动画的时候,看到了这段使用Animated的基础代码。可以看到这段代码并不使用setState
来更新状态以实现动画效果。在本文中,笔者将会总结博客和源码中的相关资料,以期了解这段代码的实现原理。
1 | const FadeInView = (props) => { |
Do Work in JS || Native Driver Animations
在这篇文章里提到了Animated的两种计算动画的方式和对应的优劣。
- 在JS线程中使用
requestAnimationFrame
计算动画参数,并使用Bridge将数据传输给原生代码 - 在动画开始前通过Bridge直接将动画信息传输给原生代码,由UI线程来计算动画参数
可以看到使用声明式的代码的方式定义动画便于使用UI线程来提高性能。
同时,不论是1还是2,都是由UI线程来渲染原生视图,因此可以跳过频繁的setState
和render
来提高性能。
Source Code
Animated.Value
在react-native库的Libraries/Animated/nodes/AnimatedValue.js
文件中描述了Animated.Value是如何工作的:
Animated构建了一个依赖的有向无环图。view属性的计算包含了两个阶段:
- Top Down Phase
当Animated.Value被更新的时候,它会寻找并标记叶节点:即需要更新的view - Bottom Up Phase
从被标记的叶节点回溯,以此得到它所需的value。(这么做的原因是某些view的属性可能是由多个value组合而成,如:transform)
Animated.[Component]
在Libraries\Animated\createAnimatedComponent.js
文件中,可以看到在mount/update的时候,使用this._propsAnimated.setNativeView
为AnimatedProps绑定了component。同时在Libraries\Animated\nodes\AnimatedProps.js
文件中,使用__connectAnimatedView
函数通过native tag标识将动画节点与对应的native view相连。