Android提供了三种类型动画:一开始的传统动画(包含两种类型:逐帧动画和补间动画(View动画))和Android3.0 之后出现的
属性动画。
逐帧动画:基于单元格的动画,每一帧显示一个不同的drawable。一帧一帧的顺序播放。
补间动画:补间动画应用于view,通过对其位置,大小,旋转和透明度的改变,让view动起来。
属性动画:属性动画几乎可以让应用程序中任何对象动起来。所有补间动画的内容,都可以通过属性动画实现。
下面逐一介绍:
注:这篇文章偏重于以xml方式实现相应动画效果。
逐帧动画
逐帧动画(Frame-by-frame Animations)从字面上理解就是一帧一帧的播放图片,类似卡通动画。
目标:
实现如下图效果:
loading步骤:
1.在res/drawable目录下新建loading_frame.xml文件:
根节点是animation-list,内部由一到多个<item>节点组成,
oneshot属性表示是否只播放一次(true:一次;false:循环播放).
item节点声明是一个动画帧,其中 android:drawable属性定义要显示的图像,android:druation代表此帧持续的时间,毫秒为单位。
注:在AndroidStudio中强制规定带animation-list节点xml文件必须放在res/drawable文件下(eclipse(ADT)貌似支持任意放res/drawable和res/anim)。在androidStudio中若放在res/anim下会报错:
2.新建页面布局activity_frame.xml:如上图布局很简单 上面一个imageview,下面两个button,都水平居中(相对于parent)。
设置imageView背景为loading_frame: android:background="@drawable/loading_frame" 这里就不贴代码了。
3.新建FrameActivity
当然为了避免animationDrawable带来的内存泄露,建议在onDestroy方法中做如下操作:
onDestroy()注意:
帧数比较多的动画不建议用逐帧动画实现,其一会显得卡顿,其二容易引起OOM。
补间动画
补间动画(Tween Animation):支持通过对View的内容进行一系列的图形变换来实现动画效果。使用补间动画进行改变透明度、缩放、旋转、平移等操作比通过手动重绘Canvas达到相似效果要消耗更少的资源,在实现上也更加简便。
补间动画类型对应补间动画使用XML语言来定义时,其XML文件被放在项目的res/anim/目录下。
由于相关的属性有点多,在这先把它们公用的属性做一下说明,然后再对每个分类下的特定属性在做对应动画效果时,进行描述。
属性对应方法及描述在上面图表中可以看到第二行有一个interpolator属性,表示动画所采用的插值器。插值器影响动画的播放速度。可以不指定,默认为加速减速插值器(@android:anim/accelerate_decelerate_interpolator")。
常用9种插值器当然安卓也支持自定义插值器,具体网上有许多相关博客教程,可自行搜索,这里先不作介绍。
说了这么多,都好像背书的赶脚了。下面我们来玩玩吧
渐变
1.在res/anim/目录下新建view_alpha.xml
view_alpha.xml(从头播放重复一次)
这里有两个属性是alpha独有的:
android:fromAlpha-动画开始时操作对象的alpha值
android:toAlpha-动画终止时操作对象的alpha值
2.在对应view上应用动画:
start_alpha3.看一下运行结果:
渐变—效果图由于默认android:fillBefore为true,所以动画运行结束时会回到初始状态
缩放
1.在res/anim/目录下新建view_scale.xml
view_scale.xml(反向播放重复两次,保持最后状态)
属性:
android:fromXScale-动画起始时,X轴坐标的伸缩尺寸。(0.0表示收缩到没有。1.0表示正常没伸缩。>1.0表示放大。<1.0表示收缩。)
android:toXScale-动画结束时X轴坐标的伸缩尺寸
android:fromYScale-动画起始时Y轴坐标的伸缩尺寸
android:toYScale-动画结束时Y轴坐标的伸缩尺寸
android:pivotX-缩放动画作用点在X轴方向上的位置。(android:pivotX=”50”表示绝对定位,相对于零点偏移50 –>Animation.ABSOLUTE
android:pivotX=”50%”表示相对控件本身 –>Animation.RELATE_TO_SELF
android:pivotX=”50%p”表示相对控件的父控件 –>Animation.RELATE_TO_PARENT)
android:pivotY-缩放动画作用点在Y轴方向上的位置(同上pivotX)
2.应用动画:
start-scale3.运行结果:
缩放-效果图旋转
1.在res/anim/目录下新建view_rotate.xml
view_rotate.xml(运行过程:先向相反的方向改变一点,然后在加速播放至超出结束值一点,然后在缓慢回到结束值)
属性:
android:fromDegrees-动画起始的角度(可正可负)
android:toDegrees-动画终止的角度(可正可负)
android:pivotX-旋转作用点在X轴方向上的位置
android:pivotY-旋转作用点在Y轴方向上的位置
2.应用动画
start-rotate3.运行结果
旋转-效果图平移
1.在res/anim/目录下新建view_translate.xml:
view-translate.xml(运行过程:先向相反的方向改变一点,然后在加速播放至超出结束值一点,然后在缓慢回到结束值)
属性:
android:fromXDelta-平移动画起始位置X轴坐标 (android:fromXDelta=”50”表示绝对定位,相对于零点偏移50 –>Animation.ABSOLUTE
android:fromXDelta=”50%”表示相对控件本身 –>Animation.RELATE_TO_SELF
android:fromXDelta=”50%p”表示相对控件的父控件–>Animation.RELATE_TO_PARENT)
android:toXDelta-平移动画结束位置X轴坐标
android:fromYDelta-平移动画起始位置Y轴坐标
android:toYDelta-平移动画结束位置Y轴坐标
2.应用
start-translate3.运行结果
平移-效果图组合
1.在res/anim/目录下新建view_set.xml:
view_set.xml属性:
android:shareInterpolator-是否对子动画设置相同的插值器
先来推测一下运行过程:前1.5秒执行渐变,然后图片以自身中心为旋转轴心,从60度转到325度,耗时1.8s。
2.应用
start-set3.运行效果:
组合-效果图额。。。跟当初推测的不一致。它一开始就转了60度然后再渐变,再转到325度。也就是说吧<rotate>的初始状态给先执行了,因为默认的fillBefore属性为true。好吧,在<rotate>中设置fillBefore为false,再试一次:
view_set.xml 修改后代码段再看看运行效果---
组合-效果图-1 没有发生任何变化!!!!是不是fillBefore失效了???看看源码,进去Animation类中,有一个mFillEabled变量(主要看上面注释):
mFillEnabled想到有个属性android:fillEnabled 与fillBefore是否被忽略有关,fillEnabled默认值是false(这时fillBefore设置为false失效)。
那将android:fillEnabled设为true试试:
view_set.xml 再次修改后代码段看看效果:
组合-效果图-终OK 要的就是这种效果(是不是很有朦胧美,哈哈)。
LayoutAnimation(View动画特殊使用场景)
LayoutAnimation作用于ViewGroup,可控制其子元素的出场效果。经常看到有些listview,它每个item都以动画的形式出现。这里我们也来实现一个类似的功能吧!
1.为子元素指定入场动画(在res/anim下新建anim_layout_item.xml)
anim_layout_item.xml2.定义layoutAnimtion-res/anim下新建anim_layout.xml
anim_layout.xml属性:
android:delay - 先从字面意思理解就是延迟,具体什么意思 通过下面实现 再看
android:animationOrder - 动画顺序 有三种选项 :normal,reverse,random 具体各自有什么效果 通过下面实现 再看
android:animation 指定子元素具体动画
3.为listview指定android:layoutAnimation属性:
布局文件-lsitview片段看看运行结果:
delay-0-效果图貌似没什么效果。那将anim_layout.xml中修改一下---android:delay="1",
delay-1-效果图从上面两图可以看到,当delay=0时,各item同时出现在页面中,当delay=1时,各item是依次以设定的动画方式出现,细心一点看,几乎当上一个item到达最左部时(完成入场动画),下一个item开始进入视图播放入场动画。所以delay应该指的是子元素的入场延迟。具体来说,第一个子元素延迟500ms*1(anim_layout_item.xml中设置duration=500,即子元素入场动画周期为500ms)才开始播放入场动画,第2个子元素延迟500ms*1*2播放入场动画,以此类推。我们再来验证一下,将delay设置为0.5,推测应该出现的效果为:上一个item大概到达中间位置时,下一个item开始入场:
delay-0.5-效果图delay的作用大概搞清楚了,下面来看看animationOrder的三个选项:normal 上面几个图都是设为这个选项的,下面就只用看其他两种选项下的运行效果。
android:animationOrder="reverse" android:animationOrder="random"从上面几个动图的效果对比可以看到
android:animationOrder属性是用来表示子元素动画的顺序的。默认即为normal:顺序显示,排在前面item先开始入场;reverse:倒序;random:随机。
当然view动画还可用于实现activity的切换效果等场景(5.0后,geogle推出的新的转场动画,还支持共享元素)。这里就不一一介绍了。
还有属性动画没有介绍,属性动画非常强大,可以通过它实现绚丽的效果。鉴于它的相关内容比较多,一时半会也说不完,下次有空再整理学习吧。
感谢:
https://developer.android.google.cn/guide/topics/graphics/view-animation.html
https://developer.android.google.cn/guide/topics/graphics/drawable-animation.html
网友评论
欢迎订阅《海水没顶的独家号》https://toutiao.io/subject/66375