xml动画的开发

来源:互联网 发布:诺查丹玛斯 知乎 编辑:程序博客网 时间:2024/06/05 16:44

引言


当今,Android、IOS二分天下,什么Tizen、COS blabla的均为蝼蚁,一看就知道是为打发领导或为花研发资金产出的产品,根本不是为了赢得市场,为的只是博得领导一笑而已,完全可以忽视。而Android开发又因为开发语言以Java为主,入门门槛极低导致基本上是个程序员,泡两天EOE,或Android Developer Training都可以过来说“哥会开发Android app了!”,那么什么才能将你的App脱颖而出呢?准确的用户痛点、良好的数据结构、简单易用的交互流程、大方前卫的设计风格等等等等都是必要的,而对于用户来说,最直观、最直接、最能被打动的就是界面,本片博客就来讲述一下Android界面开发中不可小觑的动画开发,初步决定要分为三篇博客进行详解,分别是xml动画、代码动画、插值器。本篇作为开篇,就来讲述一下xml动画的开发。


定义


  1. <?xml version="1.0" encoding="utf-8"?>  
  2.   
  3. <set xmlns:android="http://schemas.android.com/apk/res/android">  
  4.     <scale  
  5.         android:pivotX="50%p"  
  6.         android:pivotY="50%p"  
  7.         android:fromXScale="1" android:toXScale=".85"  
  8.         android:fromYScale="1" android:toYScale=".85"  
  9.         android:duration="@android:integer/config_shortAnimTime" />  
  10.   
  11.     <alpha  
  12.         android:fromAlpha="1"  
  13.         android:toAlpha=".4"  
  14.         android:duration="@android:integer/config_shortAnimTime" />  
  15. </set>  

开篇贴出一个简单的xml动画作为解析的例子(动画xml是在res/anim中的)。首先是set,set可以理解为容器,所承载的内容为动画。有了set,就可以让多个不同的属性动画同时进行播放。在上边的例子中,一个set(容器)包含了两个子动画,分别是scale——缩放动画和 alpha——透明度动画。set同样拥有android:duration属性,用来定义所有子动画持续的时间,例子中显然犯了啥,如果子动画的时间都是一样的话可以放在一个set中进行统一定义。set的常用属性有:

  1. android:duration="200"  
  2. android:interpolator="@android:interpolator/overshoot"  
  3. android:repeatCount="infinite"  
  4. android:repeatMode="reverse|restart"  

android:duration已经说过,定义的是set容器所包含的所有子动画持续的时间,单位为毫秒ms;

android:interpolator用来定义容器中所有子动画的插值器,后边的文章会详细说明什么是插值器;

android:repeatCount用来定义容器中所有子动画的重复次数,infinite为无限;

android:repeateMode用来定义容器中所有子动画重复时的模式,restart为重头播放,reverse为回放(很诡异吧)。


PS:上边这些属性所有属性动画(子动画)都有,意义相同。


现在看scale缩放动画,注意对其属性进行说明(除了android:duration都是scale缩放动画特有的属性):

android:pivotX缩放的X轴坐标在哪。此X轴所在坐标系与我们从小到大所学的略有区别:

  1. Y  
  2. |  
  3. |  
  4. -----------------------→ X  
  5. |  
  6. ↓  

区别就是Y轴是向下增长的,X则一样,是向右增长。缩放时,需要有一个基准坐标,pivotX就定义了这个基准坐标的X坐标部分,注意其属性值为50%p,就代表了是某个单位的X轴上的一半,不要忘了“p"(percent),这样就免去了我们要计算这个单位宽度再做处理的麻烦。

android:pivotY缩放基准点的Y轴坐标,别忘了是向下增长的,当然了如果是中心的话,可以像例子中一样简单的定义为50%p。

android:fromXScale缩放开始视图单位在X轴上的缩放比例为多少,1即为100%,”.5"即为50%,fromYScale同理。

android:toXScale缩放结束后视图单位在X轴上的缩放比例为多少,Android系统会自动为我们讲视图从from到to做补间动画(自动连续且自然),toYScale同理。


最后用一句话总结scale缩放动画的含义:以视图单位的中心点为准,将其大小从100%所放到85%,持续时间为300毫秒。


PS:Android内置了三个动画持续时长,分别为@android:integer/config_shortAnimTime(200ms)、@android:integer/config_mediumAnimTime(400ms)、@android:integer/config_longAnimTime(500ms),同时值得注意的是,在Android系统的设置中的开发者选项中,动画持续时间的调试选项只有在使用这几个值时才会生效,如果你使用了自定义的时间,这几个开发者选项将不能对你的应用生效。


说明完scale缩放动画后,再来看下一个alpha透明度动画,这个就要简单多了,简单的两个属性:

android:fromAlpha动画开始时的视图透明度;

android:toAlpha动画结束时的视图透明度,同样的”.4"代表40%,一个“."即带包百分比。


分析完了整个xml动画文件,总结一下这个动画文件所描述的动画行为就是:以视图中心为基准,进行100% 到85%的缩放,与此同时视图的透明度由100% 渐变到 40%,整个动画过程持续200ms。


除了上边介绍到的scale缩放动画和alpha透明度动画,xml动画还可以定义其他的动画形式:

  1. <rotate  
  2.     android:fromDegrees=""  
  3.     android:toDegrees=""  
  4.     android:pivotX=""  
  5.     android:pivotY="" />  
  6. <translate  
  7.     android:fromXDelta="" android:toXDelta=""  
  8.     android:fromYDelta="" android:toYDelta="" />  

rotate旋转动画和translate位移动画。


rotate旋转动画。围绕点(pivotX, pivotY)进行旋转,起始角度为fromDegrees,终止角度为toDegrees。

translate位移动画。X轴上从fromXDelta移动到toXDelta,Y轴上从fromYDelta移动到toYDelta,很容易理解。


XML动画的定义在Android L之前就是这些(L版本的动画只有在L平台上有效,作为beta版本目前没有多少设备覆盖量),总共包含四种动画形式:scale缩放,alpha透明度,rotate旋转,translate位移。等等,是不是缺少了什么?如果想设计围绕X或Y轴的旋转动画呢?对不起,XML动画还做不了这个,只能在代码中定义,看之后的文章吧。


使用


定义完了XML动画文件后如何进行使用呢?首先,明确一下xml动画能够应用到哪些地方:Activity、Fragment及所有View。先讲一下View,关于View的动画需要在代码中实现,假设我们已经定义了一个XML动画,名字为fade_zoom_out.xml,获取这个动画的对象:

  1. Animation animation = AnimationUtils.loadAnimation(context, R.anim.fade_zoom_out);  

Animation和AnimationUtils都是android.view.animation的子类,在API 1中都已经存在,不用担心兼容性。

让指定的View播放我们刚刚获取的动画需要调用View的startAnimation方法:

  1. public void startAnimation(Animation animation)   

而很多时候,我们在动画播放的不同时段需要对View做不同处理,这里就需要用到动画监听器AnimationListener,给动画设定监听器,所以必然是Animation类的方法:

  1. public void setAnimationListener(AnimationListener listener)  

动画监听器AnimationListener很好理解,分别监听了动画开始时、结束时、重复播放时:

  1. public static interface AnimationListener {  
  2.   
  3.         void onAnimationStart(Animation animation);  
  4.   
  5.         void onAnimationEnd(Animation animation);  
  6.   
  7.         void onAnimationRepeat(Animation animation);  
  8.     }  

XML动画在View上的应用就是这样了,很简单吧。


Activiyt的动画应用有两种方式,分别是代码中和styles.xml中主题覆盖。个人推崇通过主题定义来应用Activity动画,这样整个应用的统一性更好,有问题也比较容易修改。但是还是要说一下代码中怎么将XML动画应用在Activity上:

  1. public void overridePendingTransition(int enterAnim, int exitAnim)  

参数enterAnim和exitAnim都应该是R.anim.xxx的形式。如果没有动画则给0。这个函数需要在如startActivity或finish调用之后进行调用。enterAnim的动画会应用在进来(新)的那个Activity上,exitAnim的动画会应用在离去的Activity上。


假设现在有两个Activity,A和B。从A中执行startActivity(B),然后调用overridePendingTransition(enterAnim, exitAnim)。这时B是新的,A是旧的,需要消失。则enterAnim会应用在B上,exitAnim会应用在A上。


主题定义的方式。自定应用主题时,动画风格的属性为android:windowAnimationStyle:

  1. <item name="android:windowAnimationStyle">@style/Animation</item>  

自定义时,注意parent的选择:

  1. <style name="Animation"  
  2.        parent="@android:style/Animation.Activity">  
  3. </style>  

这样做是为了保证系统默认动画的存在,所自定义的会覆盖系统默认的,没有自定义的就直接采用系统默认的,不会出现未自定义就直接没有动画的效果。

Activity相关动画属性的设置有四个:

  1. <item name="android:activityOpenEnterAnimation"></item>  
  2. <item name="android:activityOpenExitAnimation"></item>  
  3. <item name="android:activityCloseEnterAnimation"></item>  
  4. <item name="android:activityCloseExitAnimation"></item>  

定义上特别的绕嘴,而且理解上与看字面上的第一印象并不相同。

android:activityOpenEnterAnimation指的是由打开动作(open)引出的新的Activity进入的动画是什么;

android:activityOpenExitAnimation指的是由打开动作(open)引出新的Activity后,旧的Activity的退出动画是什么;

android:activityCloseEnterAnimation指的是由上一个Activity的关闭导致Activity栈中下一个Activity出现时,所出现的这个Activity的动画效果如何;

android:activityCloseExitAnimation指的是由上一个Activity关闭导致的栈中下一个Activity出现时,这个关闭的Activity退出动画如何。


果然很绕嘴吧,下边用一个例子来解释:


假设有两个Activity A和B,分别设置了不同的动画主题。当前窗口显示的是A,点击A中的某个按钮会引出B。

当点击A中的这个按钮时,因为B是因为被打开引出的,所以B播放的是B主题的activityOpenEnterAnimation动画,而A播放的是B主题activityOpenExitAnimation动画(因为A的退出(实际是在Activity栈中后退了一个)是因为B被Open导致的,并不是因为A自身的open或close操作)。


当从B返回时,B界面需要消失,Activity栈决定A界面该出现在前台。所以可以说A的出现是因为B的close行为导致的。那么A和B所播放的动画就是A主题中定义的那些,A因为close行为导致出现,则播放activityCloseEnterAnimation,B是这个close行为中需要退出的界面,则播放activityCloseExitAnimation。

如果还是不理解,就定义几个差异显著的动画来亲身测试一下吧,绝对立竿见影的!


Activity的动画就是这样,开发过程中还是比较常见的。关于Fragment的相关动画设置改日再写,今天晚了,睡觉去~


总结


动画的使用能够为应用增光添彩,但是凡事讲求度,一旦动画被滥用,整体的用户体验非但不能提升,反而容易让用户感觉到十分做作。多讲求一些微动画吧,比如View的微微抖动。而转场动画就更应该讲求清新淡雅,如果动画效果过于强烈,用户一定觉得你的应用运行的很费劲。XML动画应用比较简单,一般适合用来做转场动画,对于View动画来说并不够灵活。

原创粉丝点击