先上自己的测试代码,有参考apidemo中的AnimationDrawable中的方法

public class AnimateActivity extends Activity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
} private static class SampleView extends View {
private AnimationDrawable mDrawable;
public SampleView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true); Drawable dr = context.getResources().getDrawable(R.drawable.ic_launcher);
dr.setBounds(0, 0, dr.getIntrinsicWidth(), dr.getIntrinsicHeight()); TranslateAnimation an = new TranslateAnimation(0, 100, 0, 200); an.setDuration(2000);
an. setRepeatCount(-1);
//因为使用的初始化方法,会默认的设置FromXType等为 ABSOLUTE,所以这个里参数传入的值是没有效果的
an.initialize(0, 0, 0, 0);//注1 mDrawable = new AnimationDrawable(dr, an);
an.startNow();
} @Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
mDrawable.draw(canvas);
invalidate();
}
}
private static class AnimationDrawable extends Drawable{
private Drawable innerDrawable;
private Animation mAnimation;
private Transformation drawTransformation;
public AnimationDrawable(Drawable drawble,Animation animation) {
this.innerDrawable = drawble;
this.mAnimation = animation;
drawTransformation = new Transformation();
}
@Override
public void draw(Canvas canvas) {
if(mAnimation!=null){
mAnimation.getTransformation(AnimationUtils.currentAnimationTimeMillis(), drawTransformation);
int save = canvas.save();
canvas.concat(drawTransformation.getMatrix());
innerDrawable.draw(canvas);
canvas.restoreToCount(save);
}else{
this.innerDrawable.draw(canvas);
}
}
@Override
public void setAlpha(int alpha) {
if(innerDrawable!=null){
innerDrawable.setAlpha(alpha);
}
}
@Override
public void setColorFilter(ColorFilter cf) {
if(innerDrawable!=null){
innerDrawable.setColorFilter(cf);
}
}
@Override
public int getOpacity() {
return innerDrawable!=null?innerDrawable.getOpacity():PixelFormat.TRANSPARENT;
} }
}

关键方法解析

注1:Animtaion.initialize 方法
这个方法是用来完成通过 设置的状态参数数值,以及状态参数的类型 转化到动画变化所需要值 的功能. 主要是与尺寸相关的参数变化

父类中缺省的转化方法,主要是针对坐标或像素变化的计算
// type 参数类型 value 参数值 size 自己大小 parentsize 父容器大小

protected float resolveSize(int type, float value, int size, int parentSize) {
switch (type) {
case ABSOLUTE:
return value;
case RELATIVE_TO_SELF:
return size * value;
case RELATIVE_TO_PARENT:
return parentSize * value;
default:
return value;
}
}

下面以系统带的四种动画来分析

1、TranslateAnimation
  位移动画主要状态参数有 :
      起始坐标[mFromXValue,mFromYValue],终止坐标 [mToXValue,mToYValue]
  参数类型:分别一一对应上边参数的类型
    mFromXType,mFromYType ,mToXType ,mToYType
    而参数类型分三种
      |-ABSOLUTE --像素值,如android:fromYDelta="100"
      |-RELATIVE_TO_SELF--相对于自身大小的比例,android:fromYDelta="100%"
      |-RELATIVE_TO_PARENT--相对与父容器的比例,android:fromYDelta="100%p"

  用构造方法TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)生成的对象,默认参数类型都为ABSOLUTE,所以调用initialize方法时,传入的参数对动画参数没有效果

2、RotateAnimation
参数:
  起始角度 mFromDegrees 最终角度 mToDegrees ,旋转中心坐标 [mPivotX,mPivotY]
参数类型: 因为旋转角度只有固定值类型中心坐标的参数类型 mPivotYValue,mPivotYType 设置与1中的参数类型相同,配置文件中设置方式也相同,如 android:pivotY="50%",动态构造方法生成的对象,参数类型默认为 ABSOLUTE

3、ScaleAnimation
  参数:
    起始大小 mFromX-mFromY ,最终大小 mToX-mToY 缩放中心坐标 [mPivotX,mPivotY]
  参数类型:
    中心坐标,则同1中的设定,并调用resolveSize 来解析,默认值为 ABSOLUTE
    起始大小和最终大小参数类型:
      |- TypedValue.TYPE_NULL :配置文件中float值,android:fromYScale="1.0" 是相对与自身大小的比例
        使用构造方法生成的对象,只有这种参数类型
      |- TypedValue.TYPE_FRACTION 配置文件为分数 [值+%(+p)],android:fromYScale="50%p",同1中参数类似,是相对于自己或者父容器的百分比值。如果为50%,等价于TypedValue.TYPE_NULL状态下的0.5
      |- TypedValue.TYPE_DIMENSION 配置文件为[值+单位],android:fromYScale="1dp",还可以使用pt,sp,px,in等单位,最终会转化成像素值
4、AlphaAnimation
    因为没有尺寸计算,所以直接调用的父类方法

动画实现过程

  设 开始时间 startTime,当前时间 currentTime 动画完成所需时间 duration

  1、 使用动态构造Animation或者调用AnimationUtils加载配置文件获得Animation实例,之后调用initialize初始化
  2、 调用start方法 或者 startNow方法,设置动画的开始时间(startTime)。
  3、 绘制时候,调用 getTransformation 方法(注2),这个方法内,会根据 (currentTime-startTime)/duration来看时间进度,并通过插值器TimeInterpolator.getInterpolation来计算出动画变化幅度
  4、 调用applyTransformation 方法,根据3获得变化幅度,将要进行的变化对应的设置到 Transformation(这个对象中包含一个进行了变化处理的Matrix),比如说位移,透明度,旋转等。//而一般自定义动画,需要重写的就是这个方法
  5、 绘制方法,将Transformation中的变化矩阵设置给canvas,绘制
  6、 如果动画未结束或者重复播放,继续调用第三步

View动画实现过程也是这个过程,见ViewGroup.drawChild只是判断动画的位置逻辑更复杂一点

注2:三个参数的重载方法:Animation.getTransformation(long currentTime, Transformation outTransformation,float scale) 第三个参数
这个参数一般不会用到,只有设计到动画中心点坐标的时候会用到。

 如ScaleAnimation和RotateAnimation
 

  ScaleAnimtaion.applyTransformation方法片段

if (mPivotX == 0 && mPivotY == 0) {
t.getMatrix().setScale(sx, sy);
} else {
t.getMatrix().setScale(sx, sy, scale * mPivotX, scale * mPivotY);
}

  RotateAnimation.applyTransformation方法片段

if (mPivotX == 0.0f && mPivotY == 0.0f) {
t.getMatrix().setRotate(degrees);
} else {
t.getMatrix().setRotate(degrees, mPivotX * scale, mPivotY * scale);
}

android动画的实现过程的更多相关文章

  1. Android动画效果之自定义ViewGroup添加布局动画

    前言: 前面几篇文章介绍了补间动画.逐帧动画.属性动画,大部分都是针对View来实现的动画,那么该如何为了一个ViewGroup添加动画呢?今天结合自定义ViewGroup来学习一下布局动画.本文将通 ...

  2. Android动画效果之Property Animation进阶(属性动画)

    前言: 前面初步认识了Android的Property Animation(属性动画)Android动画效果之初识Property Animation(属性动画)(三),并且利用属性动画简单了补间动画 ...

  3. Android动画效果之初识Property Animation(属性动画)

    前言: 前面两篇介绍了Android的Tween Animation(补间动画) Android动画效果之Tween Animation(补间动画).Frame Animation(逐帧动画)Andr ...

  4. Android动画效果之Frame Animation(逐帧动画)

    前言: 上一篇介绍了Android的Tween Animation(补间动画) Android动画效果之Tween Animation(补间动画),今天来总结下Android的另外一种动画Frame ...

  5. Android动画的理解

    基础知识 在我们开始讲Android动画这个知识点之前,我们了解下相应的基础知识点. Shape篇 一般用Shape定义的XML文件是存放在Drawable目录下,广泛应用于在Button.TextV ...

  6. Android 动画详解

    这次主要就介绍android动画,android动画目前分为三种形式,Tween Animation 这个只能应用于view对象上面的,Drawable Animation这个是帧动画,就是类似我们有 ...

  7. Android动画学习笔记-Android Animation

    Android动画学习笔记-Android Animation   3.0以前,android支持两种动画模式,tween animation,frame animation,在android3.0中 ...

  8. Android动画及图片的缩放和旋转

    Android动画有2种,一种是Tween Animation,另一种是Frame Animation,先说说Tween动画吧. Tween动画是对视图对象中的内容进行一系列简单的转换,比如位置的移动 ...

  9. Android动画原理分析

    最近在Android上做了一些动画效果,网上查了一些资料,有各种各样的使用方式,于是乘热打铁,想具体分析一下动画是如何实现的,Animation, Animator都有哪些区别等等. 首先说Anima ...

随机推荐

  1. 【Tomcat】停止冗余进程

    tomcat多次连续启动,现在通过脚本,一次执行,全部停掉 [root@YFDT-DEM1701-EPMDM ~]# cat tomcat_pid.sh #!/bin/bash cat /dev/nu ...

  2. 80C51学习 蜂鸣器

    /* 蜂鸣器分为有源和无源 其中有源是指有振荡源 ULN2003 达林顿管 输入输出反向放大 */ #include "reg52.h" typedef unsigned int ...

  3. JavaScript看书笔记01

    JavaScript看书笔记... ------------------- JavaScript允许var定义语句出现在函数内部的任意位置.JS中使用Var来显示的给变量声明 JavaScript是一 ...

  4. RSA,Miller-Rabin素数测试的源流及其证明

    一.RSA与公钥加密系统的起源与影响. 为了更好地突出公钥加密系统相对私钥加密系统的优势,让我们从这两个问题开始: 这个世界上如果没有公钥加密系统会怎么样呢?全用私钥加密系统会出现什么问题呢? 首先, ...

  5. quartus2中FPGA管脚分配保存方法(转)

    一.摘要 将Quartus II中FPGA管脚的分配及保存方法做一个汇总. 二.管脚分配方法 FPGA 的管脚分配,除了在QII软件中,选择“Assignments ->Pin”标签(或者点击按 ...

  6. 记一次被yield return坑的历程。

    事情的经过是这样的: 我用C#写了一个很简单的一个通过迭代生成序列的函数. public static IEnumerable<T> Iterate<T>(this Func& ...

  7. JavaScript基本语法2

    javaScript中要显示> .<必须使用&gt .&lt,如果是不显示但是要作为条件可以直接使用>.<. 接下来是JavaScirpt函数: 要使用func ...

  8. 使用VMware Workstation安装win7镜像文件时遇见的错误

    最近打算使用虚拟机安装个系统玩玩,就去网站上找了教程安装下win7系统.但是在安装过程中遇见两个问题,现在把遇见的问题总结记录一下,以及解决方法罗列一下. 我当时使用的是VMware 12版的,系统是 ...

  9. 理解javascript 对象,原型对象、闭包

    javascript作为一个面向对象的语言,理解 对象.原型.闭包.模块模式等技术点对于成为一名合格的javascript程序员相当重要,多年没写过blog,今天就先拋个玉,在下基本也不做前端,但颇感 ...

  10. ASP.NET Core 运行原理解剖[4]:进入HttpContext的世界

    HttpContext是ASP.NET中的核心对象,每一个请求都会创建一个对应的HttpContext对象,我们的应用程序便是通过HttpContext对象来获取请求信息,最终生成响应,写回到Http ...