android动画的实现过程
先上自己的测试代码,有参考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动画的实现过程的更多相关文章
- Android动画效果之自定义ViewGroup添加布局动画
前言: 前面几篇文章介绍了补间动画.逐帧动画.属性动画,大部分都是针对View来实现的动画,那么该如何为了一个ViewGroup添加动画呢?今天结合自定义ViewGroup来学习一下布局动画.本文将通 ...
- Android动画效果之Property Animation进阶(属性动画)
前言: 前面初步认识了Android的Property Animation(属性动画)Android动画效果之初识Property Animation(属性动画)(三),并且利用属性动画简单了补间动画 ...
- Android动画效果之初识Property Animation(属性动画)
前言: 前面两篇介绍了Android的Tween Animation(补间动画) Android动画效果之Tween Animation(补间动画).Frame Animation(逐帧动画)Andr ...
- Android动画效果之Frame Animation(逐帧动画)
前言: 上一篇介绍了Android的Tween Animation(补间动画) Android动画效果之Tween Animation(补间动画),今天来总结下Android的另外一种动画Frame ...
- Android动画的理解
基础知识 在我们开始讲Android动画这个知识点之前,我们了解下相应的基础知识点. Shape篇 一般用Shape定义的XML文件是存放在Drawable目录下,广泛应用于在Button.TextV ...
- Android 动画详解
这次主要就介绍android动画,android动画目前分为三种形式,Tween Animation 这个只能应用于view对象上面的,Drawable Animation这个是帧动画,就是类似我们有 ...
- Android动画学习笔记-Android Animation
Android动画学习笔记-Android Animation 3.0以前,android支持两种动画模式,tween animation,frame animation,在android3.0中 ...
- Android动画及图片的缩放和旋转
Android动画有2种,一种是Tween Animation,另一种是Frame Animation,先说说Tween动画吧. Tween动画是对视图对象中的内容进行一系列简单的转换,比如位置的移动 ...
- Android动画原理分析
最近在Android上做了一些动画效果,网上查了一些资料,有各种各样的使用方式,于是乘热打铁,想具体分析一下动画是如何实现的,Animation, Animator都有哪些区别等等. 首先说Anima ...
随机推荐
- Words used when reading Redis documents
Redis-----------------First pageevolution n.演变,进化,发展 closely adv.紧密地trade off 交换物品,权衡achieved adj.高度 ...
- 8.23.3 IO-转换流的作用
Reader和Writer最重要的子类是InputStreamReader和OutputStreamWriter类. InputStreamReader类包含了一个底层输入流,可以从中读取原始字节.它 ...
- jquery layer弹窗弹层插件 (转)
/* 先去官网下载最新的js http://sentsin.com/jquery/layer/ ①引用jquery ②引用layer.min.js */ 触发弹层的事件可自由绑定,如: $('#id ...
- 使用webpack热加载,开发多页面web应用
我们一般使用webpack热加载开发SPA应用,但工作中难免会遇到一些多页面的demo或项目. 故参考 kingvid-chan 的代码,搭了一个使用HRM开发多页面web应用的脚手架,刚好也进一步学 ...
- Spring框架IOC,DI概念理解
1.什么是框架? 框架是一种重复使用的解决方案,针对某个软件开发的问题提出的. Spring框架,它是一个大型的包含很多重复使用的某个领域的解决方案. Spring的理念:不要重复发明轮子. 2.Sp ...
- React渲染问题研究以及Immutable的应用
写在前面 这里主要介绍自己在React开发中的一些总结,关于react的渲染问题的一点研究. 另外本人一直希望在React项目中尝试使用,因此在之前已经介绍过immutable的API,可以参看这里I ...
- hdu3720 Arranging Your Team
Arranging Your Team Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...
- 工具类:将其他编码类型转换成UTF-8或者其他类型的工具类
将其他编码类型转换成UTF-8或者其他类型的工具类 public static String changeUTF(String str) { String newStr = null; try { n ...
- Akka(23): Stream:自定义流构件功能-Custom defined stream processing stages
从总体上看:akka-stream是由数据源头Source,流通节点Flow和数据流终点Sink三个框架性的流构件(stream components)组成的.这其中:Source和Sink是stre ...
- JavaScript: 使用 atan2 来绘制 箭头 和 曲线
最近搞Canvas绘图,知道了JavaScript中提供了atan2(y,x)这样一个三角函数.乍眼一看,不认识,毕竟在高中时,学过的三角函数有:sin,cos,arcsin,arccos,tan,a ...