Android中的动画(XML方式)实践(逐帧动画与补间动画)

Android提供了三种类型动画:一开始的传统动画(包含两种类型:逐帧动画补间动画(View动画))和Android3.0 之后出现的

属性动画

逐帧动画:基于单元格的动画,每一帧显示一个不同的drawable。一帧一帧的顺序播放。

补间动画:补间动画应用于view,通过对其位置,大小,旋转和透明度的改变,让view动起来。

属性动画:属性动画几乎可以让应用程序中任何对象动起来。所有补间动画的内容,都可以通过属性动画实现。

下面逐一介绍:

注:这篇文章偏重于以xml方式实现相应动画效果。

逐帧动画

逐帧动画(Frame-by-frame Animations)从字面上理解就是一帧一帧的播放图片,类似卡通动画。

目标:

实现如下图效果:

loading

步骤:

1.在res/drawable目录下新建loading_frame.xml文件:

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下会报错:

错误提示:1
错误提示:2

2.新建页面布局activity_frame.xml:如上图布局很简单 上面一个imageview,下面两个button,都水平居中(相对于parent)。

   设置imageView背景为loading_frame: android:background="@drawable/loading_frame"  这里就不贴代码了。

3.新建FrameActivity

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_alpha

3.看一下运行结果:

渐变—效果图

由于默认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-scale

3.运行结果:

缩放-效果图

旋转

1.在res/anim/目录下新建view_rotate.xml

view_rotate.xml

(运行过程:先向相反的方向改变一点,然后在加速播放至超出结束值一点,然后在缓慢回到结束值)

属性:

android:fromDegrees-动画起始的角度(可正可负)

android:toDegrees-动画终止的角度(可正可负)

android:pivotX-旋转作用点在X轴方向上的位置

android:pivotY-旋转作用点在Y轴方向上的位置

2.应用动画

start-rotate

3.运行结果

旋转-效果图

平移

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-translate

3.运行结果

平移-效果图

组合

1.在res/anim/目录下新建view_set.xml:

view_set.xml

属性:

android:shareInterpolator-是否对子动画设置相同的插值器

先来推测一下运行过程:前1.5秒执行渐变,然后图片以自身中心为旋转轴心,从60度转到325度,耗时1.8s。

2.应用

start-set

3.运行效果:

组合-效果图

额。。。跟当初推测的不一致。它一开始就转了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.xml

2.定义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



最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容