Android动画之ViewAnimation和DrawableAnimation

概述

继上一篇Android的LayoutAnimation,在Android中给单个View设置动画所用到的动画是视图动画(补间动画)和帧动画(DrawableAnimation)

ViewAnimation

ViewAnimation 是Android 中最简单的动画,可以分为AlphaAnimation,RotateAnimation,ScaleAnimation,TranslateAnimationAnimationSet,其中动画监听器为AnimationListener

他们都可以在代码和xml中设置生效,

  • xml生成动画,需要放在anim目录下

"1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android"
    android:duration="2000"
    android:fromXDelta="-100%"
    android:fromYDelta="0"
    android:toXDelta="100%p"
    android:toYDelta="0"/>

    
 Animation animation = AnimationUtils.loadAnimation(mActivity, R.anim.move_left_to_right_translate);
    animation.setAnimationListener(animationListener);

 mText1.startAnimation(animation);
  • 代码生成动画
 private TranslateAnimation createTranslateAnimation() {
    TranslateAnimation translateAnimation =
        new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 100f,
            Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 100f);
    translateAnimation.setDuration(1000);
    return translateAnimation;
  }

关于属性中的 数值 % %p 的异同,可以参考自定义控件三部曲之动画篇(一)——alpha、scale、translate、rotate、set的xml属性及用法

xml中的通用属性

  • android:duration 动画从开始到结束持续的时长,单位为毫秒
  • android:detachWallpaper 设置是否在壁纸上运行,只对设置了壁纸背景的窗口动画(window animation)有效。设为true,则动画只在窗口运行,壁纸背景保持不变
  • android:fillAfter 设置为true时,动画执行完后,View会停留在动画的最后一帧;默认为false;如果是动画集,需在标签中设置该属性才有效
  • android:fillBefore 设置为true时,动画执行完后,View回到动画执行前的状态,默认即为true
  • android:fillEnabled 设置为true时,android:fillBefore的值才有效,否则android:fillBefore会被忽略
  • android:repeatCount 设置动画重复执行的次数,默认为0,即不重复;可设为-1或infinite,表示无限重复
  • android:repeatMode 设置动画重复执行的模式,可设为以下两个值其中之一:

    • restart 动画重复执行时从起点开始,默认为该值
    • reverse 动画会反方向执行
  • android:startOffset 设置动画执行之前的等待时长,毫秒为单位;重复执行时,每次执行前同样也会等待一段时间

  • android:zAdjustment 表示被设置动画的内容在动画运行时在Z轴上的位置,取值为以下三个值之一:

    • normal 默认值,保持内容在Z轴上的位置不变
    • top 保持在Z周最上层
    • bottom 保持在Z轴最下层
  • android:interpolator 设置动画速率的变化,比如加速、减速、匀速等,需要指定Interpolator资源,后面再详细讲解

  • 标签还有个android:shareInterpolator属性,设置为true时则可将interpolator应用到所有子元素中

自定义ViewAnimation

自定义Animation原理: 在ViewGroupdrawChild方法获取该ViewTransformation值,然后调用canvas.concat(transformationToApply.getMatrix())通过矩阵运算完成动画,如果动画尚未完成,继续调用invalidate启动下次绘制,从而完成动画的绘制.如果涉及到3D变换,需要用到Camera对象

示例

public class Custom3DAnimation extends Animation {
  private int mCenterWidth;
  private int mCenterHeight;
  private Camera mCamera = new Camera();
  private float mRotateY = 0.0f;

  @Override
  public void initialize(int width, int height, int parentWidth, int parentHeight) {
    super.initialize(width, height, parentWidth, parentHeight);
    setDuration(2000);// 设置默认时长
    setFillAfter(true);// 动画结束后保留状态
    setInterpolator(new BounceInterpolator());// 设置默认插值器
    mCenterWidth = width / 2;
    mCenterHeight = height / 2;
  }

  // 暴露接口-设置旋转角度
  public void setRotateY(float rotateY) {
    mRotateY = rotateY;
  }

  @Override
  protected void applyTransformation( float interpolatedTime, Transformation t) {
    final Matrix matrix = t.getMatrix();
    mCamera.save();
    mCamera.rotateY(mRotateY * interpolatedTime);// 使用Camera设置旋转的角度
    mCamera.getMatrix(matrix);// 将旋转变换作用到matrix上
    mCamera.restore();
    // 通过pre方法设置矩阵作用前的偏移量来改变旋转中心
    matrix.preTranslate(mCenterWidth, mCenterHeight);
    matrix.postTranslate(-mCenterWidth, -mCenterHeight);
  }
}

applyTransformation方法的第一个参数interpolatedTime是插值器的时间因子,取值在0到1之间;第二个参数Transformation是矩阵的封装类,一般使用它来获得当前的矩阵Matrix对象,然后对矩阵进行操作,就可以实现动画效果了

缺点:ViewAnimation只能作用于View上,而且在动画结束后其事件响应还在源位置

DrawableAnimation

Drawable Animation 可以让我们按顺序加载一系列的资源来创建一个动画。就像电影一帧帧的播放那样.最终会生成一个Drawable.接下来我们看一下两种可以实现动画的Drawable.

AnimationDrawable

这种方式有一个缺点,就是会有很多的资源文件,使用不当,会导致内存溢出

  • 定义xml文件,需要放在drawable目录下


<animation-list android:oneshot="false"
                xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:duration="83" android:drawable="@drawable/ic_loading_white1" />
    <item android:duration="83" android:drawable="@drawable/ic_loading_white2" />
    <item android:duration="83" android:drawable="@drawable/ic_loading_white3" />
    <item android:duration="83" android:drawable="@drawable/ic_loading_white4" />
animation-list>

在代码中会生成一个AnimationDrawable的实例,

mIcon1.setImageResource(R.drawable.progress_drawable_white);

AnimationDrawable animationDrawable = (AnimationDrawable) mIcon2.getDrawable();
    if (null != animationDrawable){
      if (!animationDrawable.isRunning()) {
        _v.setText("停止");
        animationDrawable.start();
      } else {
        _v.setText("开始");
        animationDrawable.stop();
      }
    }

AnimatedRotateDrawable

在Android中还有一种是为Rotate而设置的Drawable动画,使用的标签是
animated-rotate,会生成AnimatedRotateDrawable,但是AnimatedRotateDrawable是一个被@hide的类,使用如下

  • 定义xml,放在drawable下

<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_loading_white1"
    android:pivotX="50%"
    android:pivotY="50%"/>

这种方式之需要一张图片即可实现旋转动画

  • 代码控制
// 因为AnimatedRotateDrawable是不可见的,但是其实现了Animatable接口,因此可以用接口来实现控制操作
Drawable drawable = mIcon1.getDrawable();
    if (null != drawable) {
      Animatable animatable = (Animatable) drawable;
      if (!animatable.isRunning()) {
        v.setText("停止");
        animatable.start();
      } else {
        v.setText("开始");
        animatable.stop();
      }
    }

缺点:DrawableAnimation比较消耗资源,操作不当,会导致oom

具体源码地址;AndroidAnimations

参考:Android样式的开发:View Animation篇
Android Heroes Reading Notes 3
居中显示并旋转 android Button 里的属性drawableLeft

扩展阅读
自定义控件三部曲之动画篇(一)——alpha、scale、translate、rotate、set的xml属性及用法
Android 动画,看完这些还不够
Android动画三部曲之一 View Animation & LayoutAnimation

你可能感兴趣的:(Android基础,Android动画)