Android动画

  • View动画
  • 帧动画
  • 属性动画

View动画

简易的动画效果

  • 仅仅是动的 View 的绘制地方,View 真正的位置并没有一起动画
  • 一般会用作直接作用页面中的 View 上,实现基本的动画效果:平移、旋转、缩放、透明度、或前几者的交集
    • 平移动画-TranslateAnimation
    • 缩放动画-ScaleAnimation
    • 旋转动画-RotateAnimation
    • 透明度动画-AlphaAnimation

自定义View动画

自定义View动画是数学中矩阵变换的细节, 只需要知道自定义View的方法并且在需要的时候参考矩阵变换的细节就可以写出特定的自定义动画

  • 集成Animation抽象类
  • 重写initialize方法, 做一些初始化工作
  • 重写applyTransformation方法,进行相对应的矩阵变换

View动画的特殊使用场景

  • ViewGroup中控制子元素的出场效果

    • 为子元素定义入场动画-res/anim/anim_item.xml

      1. <?xml version="1.0" encoding="utf-8"?>
      2. <set xmlns:android="http://schemas.android.com/apk/res/android"
      3. android:duration="300"
      4. android:interpolator="@android:anim/accelerate_interpolator"
      5. android:shareInterpolator="true">
      6. <alpha
      7. android:fromAlpha="0.0"
      8. android:toAlpha="1.0" />
      9. <translate
      10. android:fromXDelta="500"
      11. android:toXDelta="0.0"/>
      12. </set>
    • 定义LayoutAnimation,-res/anim/anim_layout.xml. 也是view动画,为ViewGroup的子元素加上出场效果

      1. <?xml version="1.0" encoding="utf-8"?>
      2. <layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
      3. android:delay="0.5"
      4. android:animationOrder="normal"
      5. android:animation="@anim/anim_item">
      6. </layoutAnimation>
    • 为ViewGroup来指定android:layoutAnimation属性

  1. <ListView
  2. //........
  3. android: layoutAnimation="@ anim/ anim_ layout"
  • Activity实现不同Activity之间的切换效果, 调用overridePendingTransition(int enterAnim, int exitAnim)
    • enterAnim-Activity被打开时,所需的动画资源id
    • exitAnim-Activity被暂停时,所需的动画资源id
  1. //启动Activity
  2. Intent intent = new Intent(this, TestActivity.class);
  3. startActivity(intent);
  4. overridePendingTransition(R.anim.enter_ anim, R.anim.exit_ anim);
  5. //退出Activity
  6. @Override
  7. public void finish() {
  8. super.finish();
  9. overridePendingTransition(R.anim.enter_ anim, R.anim.exit_ anim);
  10. }
  • Fragment添加切换动画, 通过FragmentTransaction的setCustomAnimations

帧动画

就和看的动画片一样,每一帧代表一个画面动作,当快速逐帧显示时,速度到达人眼无法分辨每一帧时,就达到了动画的效果。使用场景,在开发中使用的真是少之又少:

  • 设备的开关机动画
  • “复杂” 的动画效果,看似不可能完成的动画

    其实真正用到帧动画时,更多的时候我们还不如使用 GIF 图片代替,现在几个主流图片加载框架都支持 GIF 图片,同时也能控制 GIF 的播放时机。

帧动画使用

  • 通过xml来定义AnimationDrawable
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
  3. <item android:drawable="@drawable/account" android:duration="500"/>
  4. <item android:drawable="@drawable/account_2x" android:duration="500"/>
  5. <item android:drawable="@drawable/account_3x" android:duration="500"/>
  6. </animation-list>
  • 将上述Drawable作为View的背景,并且通过Drawable来播放动画
  1. Button mButton = (Button) findViewById(R.id.button1);
  2. mButton.setBackgroundResource(R.drawable.frame_ animation);
  3. AnimationDrawable drawable = (AnimationDrawable) mButton.getBackground();
  4. drawable.start();

属性动画

原理

属性动画要求动画作用的对象提供该属性的get和set方法,属性动画根据外接传递的该属性的初始值和最终值,以动画的效果多次去调用set方法,每次传递给set方法的值都不一样,确切来说是随着时间的推移,所传递的值越来越接近最终值。对object的属性abc做动画,要让动画生效,需要满足两个条件

  • object提供属性的方法
    • setAbc方法
    • getAbc方法—如果动画没有传递初始值,因为系统要获取属性的初始值,否则会crash
  • object的属性改变必须能够通过某种方式反映出来, 譬如UI的改变之类,否则就是动画无效果了

否则

  • 给对象加上get和set方法—前提是有权限
  • 用一个类来包装原始对象,间接为其提供get和set方法
  • 使用ValueAnimator,监听动画过程,自己实现属性改变

view动画 vs 属性动画

  • View 动画只能为 View 添加动画效果,且不能监听 View 相关属性的变化过程。
  • View 动画提供的动画能力较为单一,目前只支持帧动画、缩放动画、位移动画、旋转动画、透明度动画以及这些动画的集合动画。
  • View动画改变的是 View 的绘制效果,View 的真正位置和相关属性并不会改变,这也就造成了点击事件的触发区域是动画前的位置而不是动画后的位置的原因。

    属性动画

  • 属性动画作用对象不局限在 View 上,而是任何提供了 Getter 和 Setter 方法的对象的属性上。

  • 属性动画没有直接改变 View 状态的能力,而是通过动态改变 View 相关属性的方式来改变 View 的显示效果。
  • 属性动画使用更方便,可以用更简洁的代码实现相关的动画效果。
  • 属性动画上手难度较高,对于 propertyName 需要自己去挖掘,或者自己通过 Wrapper 的方式去自定义 propertyName。
  • 属性动画是 Android3.0 以上系统提供的能力,在 3.0 以下需导入 nineoldandroids 三方库解决兼容性问题。

使用动画注意事项

  • OOM—帧动画图片数量多或者较大的时候容易出现OOM
  • 内存泄露
    • 属性动画有一类无限循环的动画, 需要在Activity退出的时候及时停止否则会内存泄露
    • View动画不存在该问题
  • 进行动画尽量使用dp,因为px会在不同设备上有不同的效果
  • 硬件加速-开启硬件加速会提高动画流畅性