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 ...
随机推荐
- Windbg调试互斥体(Mutex)死锁
一. 测试代码 #include <windows.h> #include <tchar.h> #include <process.h> HANDLE hMutex ...
- Windows7 中常用的一些DOS命令总结
Windows7 中常用的一些DOS命令总结... ----------------------- -------------------------------------------- dos,是 ...
- Android ViewPager无法使用wrap_content属性自适应高度
使用ViewPager的时候发现一个问题,当设置ViewPager控件的height属性为wrap_content时,控件高度一直是0,无法正常显示,在网上找到了解决办法,重写ViewPager的on ...
- python增量爬虫pyspider
1.为了能够将爬取到的数据存入本地数据库,现在本地创建一个MySQL数据库example,然后 在数据库中建立一张表格test,示例如下: DROP TABLE IF EXISTS `test`; C ...
- python汉字输出编码问题
python中文输出乱码问题困扰了多少初学者,我在这方面栽了不知道多少跟头.现在我把我碰到的问题和解决的方法写出来与大家分享一下: 1输出乱码 所谓的乱码是指“鎴戞槸涓枃瀛楃涓”这样的内容.为什么 ...
- Git安装配置(完整版)
首先安装Windows客户端的git和TortoiseGit. 安装这两个软件还是蛮重要的,很多选项不能乱选. 为了写个完整的博客,我是装了又卸,卸了又装. 1.安装git 下载:https://gi ...
- kettle使用正则表达式动态获取excel表
- java中接口实现多态举例
public class Test4 { public static void main(String[] args){ Instrument ss[]={new Wind(),new Piano() ...
- python学习总结(面向对象进阶)
-------------------类属性和实例属性关系------------------- 1.类属性和实例属性关系 1.实例属性 实例对象独有的属性 2.类属性 ...
- hdu 6068--Classic Quotation(kmp+DP)
题目链接 Problem Description When online chatting, we can save what somebody said to form his ''Classic ...