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 ...
随机推荐
- Andrew Ng机器学习课程笔记--week7(SVM)
本周主要学习SVM 一. 内容概要 Large Margin Classification Optimization Objective(优化Objective(损失函数)) Large Margin ...
- Core Graphics框架
在iOS中常用的框架是Quartz 2D,它是Core Graphics框架的一部分,是一个强大的二维图像绘制引擎.我们日常开发所用到的UIKit的组件都是由Core Graphics框架进行绘制的. ...
- WebDriver多浏览器测试
selenium2 基于对象的测试,在selenium2中一共支持以下浏览器: Firefox(FirefoxDriver) IE(InternetExplorerDriver) Chrome(Chr ...
- python之VSCode安装
[之前发布到本人的51cto博客,现转过来] 1.安装python3.5(3.6版本亲测无法实现命令补全功能) 2.安装VSCode(我的版本:VSCode-win32-1.7.2) 3.安装Pyth ...
- MySQL(二)之服务管理与初始化文件修改和连接MySQL
上一篇给大家介绍了怎么在linux和windows中安装mysql,本来是可以放在首页的,但是博客园说“安装配置类文件”不让放在首页.接下来给大家介绍一下在linux和windows下MySQL的一下 ...
- TC358743XBG:HDMI转MIPI CSI参考设计
TC358743XBG参考设计电路图如下, 功能HDMI转MIPI CSI ,通信方式:IIC,分辨率1920*1080,封装形式BGA64.
- wireshark 随笔
在进行通信开发的过程中,我们往往会把本机既作为客户端又作为服务器端来调试代码,使得本机自己和自己通信.但是wireshark此时是无法抓取到数据包的,需要通过简单的设置才可以. 具体方法如下: ①:以 ...
- 使用 PUTTY 操作 Google Cloud
目的: 使用putty连接Google Cloud 实例. 总说: 首先要用 PuTTYgen生成 private key 和 public key, 之后 登录Google Cloud 将生成的 ...
- Java中常见数据结构Set之HashSet
今天来说说Java集合中的Set系列之HashSet. Set我们众所周知的就是虑重功能, 我们平时在项目开发中也常用到这个特性的.那么Set为何能够虑重呢? 接下来我们就看下源码吧. Set ...
- CentOS 7 更改网卡名为eth0
今天用VBOX安装了CentOS7, 但是安装完之后,发现没有ifconfig命令,在网上搜了一下解决办法,在可以连网状态下,输入下面命令即可 然后就可以用ifconfig命令了. 使用ifconfi ...