学习和实践react已经有一段时间了,在经历了从最初的彷徨到解决痛点时的兴奋,再到不断实践后遭遇问题时的苦闷,确实被这一种新的思维方式和开发模式所折服,但react也不是万能的,在很多场景下滥用反而会适得其反,这里不展开讨论。
有了react的实践经验,结合之前自己的一点ios开发经验,决定继续冒险,开始react-native学习和实践,目前主要是从常规的native功能入手,逐步用react-native实现,基础知识如开发环境搭建、调试工具等官方文档有很清楚的指引,不再赘述,这里主要是想把实际学习实践中遇到的坑或者有意思的经历记录下来,为广大react-native初学者提供一点参考。O(∩_∩)O~
话不多说,进入正题,今天要实现的是一个加载动画,效果如下:
很简单一个动画,不是么?用native实现实在是小菜一碟,现在我们试着用RN来实现它!
先将动画的视图结构搭建出来,这个比较简单,就是4个会变形的View顺序排列:
1 2 3 4 5 6 |
<View style={styles.square}> <Animated.View style={[styles.line,{height:this.state.fV}]}> <Animated.View style={[styles.line,{height:this.state.sV}]}> <Animated.View style={[styles.line,{height:this.state.tV}]}> <Animated.View style={[styles.line,{height:this.state.foV}]}> </View> |
这里的视图结构很普通,只不过在RN中,需要施加动画的视图,都不能是普通的View,而是Animated.View,包括施加动画的图片,也应该是Animated.Image,需要注意。
RN继承了react的核心思想,基于虚拟DOM和数据驱动的模式,用state来管理视图层,所以RN的动画和react的动画类似,都是通过改变state从而执行render进行视图重绘,展现动画。
毫无疑问,先从Animated库下手,这是facebook官方提供的专门用于实现动画的库,它比较强大,集成了多种常见的动画形式,正如官方文档写道:
Animated focuses on declarative relationships between inputs and outputs, with configurable transforms in between, and simple start/stop methods to control time-based animation execution.
它专注于输入和输出之间的对应关系,其间是可以配置的各种变形,通过简单的开始和停止方法来控制基于时间的动画。
所以使用这个库的时候,需要清楚知道动画的输入值,不过这并不代表需要知道每一个时刻动画的精确属性值,因为这是一种插值动画,Animated只需要知道初始值和结束值,它会将所有中间值动态计算出来运用到动画中,这有点类似于CSS3中的关键帧动画。它提供了spring、decay、timing三种动画方式,其实这也就是三种不同的差值方式,指定相同的初始值和结束值,它们会以不同的函数计算中间值并运用到动画中,最终输出的就是三种不同的动画,比如官方给出的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
class Playground extends React.Component { constructor(props: any) { super(props); this.state = { bounceValue: new Animated.Value(0),//这里设定了动画的输入初始值,注意不是数字0 }; } render(): ReactElement { return ( Animated.Image //这里不是普通Image组件 source={{uri: 'http://i.imgur.com/XMKOH81.jpg'}} style={{ flex: 1, transform: [ //添加变换,transform的值是数组,包含一系列施加到对象上的变换 {scale: this.state.bounceValue}, // 变换是缩放,缩放值state里的bounceValue,这个值是一个动态值,也是动画的根源 ] }} /> ); } componentDidMount() { this.state.bounceValue.setValue(1.5); // 组件加载的时候设定bounceValue,因此图片会被放大1.5倍 Animated.spring( //这里运用的spring方法,它的差值方式不是线性的,会呈现弹性的效果 this.state.bounceValue, //spring方法的第一个参数,表示被动态插值的变量 { toValue: 0.8, //这里就是输入值的结束值 friction: 1, //这里是spring方法接受的特定参数,表示弹性系数 } ).start();// 开始spring动画 } } |
可以想象该动画效果大致为:图片首先被放大1.5倍呈现出来,然后以弹性方式缩小到0.8倍。这里的start方法还可以接收一个参数,参数是一个回调函数,在动画正常执行完毕之后,会调用这个回调函数。
Animated库不仅有spring/decay/timing三个方法提供三种动画,还有sequence/decay/parallel等方法来控制动画队列的执行方式,比如多个动画顺序执行或者同时进行等。
介绍完了基础知识,我们开始探索这个实际动画的开发,这个动画需要动态插值的属性其实很简单,只有四个视图的高度值,其次,也不需要特殊的弹性或者缓动效果。所以我们只需要将每个视图的高度依次变化,就可以了,so easy!
开始尝试:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
Animated.timing( this.state.fV, { toValue: 100, duration:500, delay:500, } ).start(); Animated.timing( d="crayon-5812f4bf41d0a675141814-9"> Animated.timing( ct也不是万能的,在很多场景下滥用反而会适得其反,这里不展开讨论。
有了react的实践经验,结合之前自己的一点ios开发经验,决定继续冒险,开始react-native学习和实践,目前主要是从常规的native功能入手,逐步用react-native实现,基础知识如开发环境搭建、调试工具等官方文档有很清楚的指引,不再赘述,这里主要是想把实际学习实践中遇到的坑或者有意思的经历记录下来,为广大react-native初学者提供一点参考。O(∩_∩)O~ 话不多说,进入正题,今天要实现的是一个加载动画,效果如下: 很简单一个动画,不是么?用native实现实在是小菜一碟,现在我们试着用RN来实现它! 先将动画的视图结构搭建出来,这个比较简单,就是4个会变形的View顺序排列:
这里的视图结构很普通,只不过在RN中,需要施加动画的视图,都不能是普通的View,而是Animated.View,包括施加动画的图片,也应该是Animated.Image,需要注意。 RN继承了react的核心思想,基于虚拟DOM和数据驱动的模式,用state来管理视图层,所以RN的动画和react的动画类似,都是通过改变state从而执行render进行视图重绘,展现动画。 毫无疑问,先从Animated库下手,这是facebook官方提供的专门用于实现动画的库,它比较强大,集成了多种常见的动画形式,正如官方文档写道:
它专注于输入和输出之间的对应关系,其间是可以配置的各种变形,通过简单的开始和停止方法来控制基于时间的动画。 所以使用这个库的时候,需要清楚知道动画的输入值,不过这并不代表需要知道每一个时刻动画的精确属性值,因为这是一种插值动画,Animated只需要知道初始值和结束值,它会将所有中间值动态计算出来运用到动画中,这有点类似于CSS3中的关键帧动画。它提供了spring、decay、timing三种动画方式,其实这也就是三种不同的差值方式,指定相同的初始值和结束值,它们会以不同的函数计算中间值并运用到动画中,最终输出的就是三种不同的动画,比如官方给出的示例:
可以想象该动画效果大致为:图片首先被放大1.5倍呈现出来,然后以弹性方式缩小到0.8倍。这里的start方法还可以接收一个参数,参数是一个回调函数,在动画正常执行完毕之后,会调用这个回调函数。 Animated库不仅有spring/decay/timing三个方法提供三种动画,还有sequence/decay/parallel等方法来控制动画队列的执行方式,比如多个动画顺序执行或者同时进行等。 介绍完了基础知识,我们开始探索这个实际动画的开发,这个动画需要动态插值的属性其实很简单,只有四个视图的高度值,其次,也不需要特殊的弹性或者缓动效果。所以我们只需要将每个视图的高度依次变化,就可以了,so easy! 开始尝试:
|