Android中的动画具体解释系列【3】——自己定义动画研究
在上一篇中我们使用到了位移动画TranslateAnimation,以下我们先来看看TranslateAnimation是怎样实现Animation中的抽象方法的:
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ package android.view.animation; import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet; /**
* An animation that controls the position of an object. See the
* {@link android.view.animation full package} description for details and
* sample code.
*
*/
public class TranslateAnimation extends Animation {
private int mFromXType = ABSOLUTE;
private int mToXType = ABSOLUTE; private int mFromYType = ABSOLUTE;
private int mToYType = ABSOLUTE; private float mFromXValue = 0.0f;
private float mToXValue = 0.0f; private float mFromYValue = 0.0f;
private float mToYValue = 0.0f; private float mFromXDelta;
private float mToXDelta;
private float mFromYDelta;
private float mToYDelta; /**
* Constructor used when a TranslateAnimation is loaded from a resource.
*
* @param context Application context to use
* @param attrs Attribute set from which to read values
*/
public TranslateAnimation(Context context, AttributeSet attrs) {
super(context, attrs); TypedArray a = context.obtainStyledAttributes(attrs,
com.android.internal.R.styleable.TranslateAnimation); Description d = Description.parseValue(a.peekValue(
com.android.internal.R.styleable.TranslateAnimation_fromXDelta));
mFromXType = d.type;
mFromXValue = d.value; d = Description.parseValue(a.peekValue(
com.android.internal.R.styleable.TranslateAnimation_toXDelta));
mToXType = d.type;
mToXValue = d.value; d = Description.parseValue(a.peekValue(
com.android.internal.R.styleable.TranslateAnimation_fromYDelta));
mFromYType = d.type;
mFromYValue = d.value; d = Description.parseValue(a.peekValue(
com.android.internal.R.styleable.TranslateAnimation_toYDelta));
mToYType = d.type;
mToYValue = d.value; a.recycle();
} /**
* Constructor to use when building a TranslateAnimation from code
*
* @param fromXDelta Change in X coordinate to apply at the start of the
* animation
* @param toXDelta Change in X coordinate to apply at the end of the
* animation
* @param fromYDelta Change in Y coordinate to apply at the start of the
* animation
* @param toYDelta Change in Y coordinate to apply at the end of the
* animation
*/
public TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta) {
mFromXValue = fromXDelta;
mToXValue = toXDelta;
mFromYValue = fromYDelta;
mToYValue = toYDelta; mFromXType = ABSOLUTE;
mToXType = ABSOLUTE;
mFromYType = ABSOLUTE;
mToYType = ABSOLUTE;
} /**
* Constructor to use when building a TranslateAnimation from code
*
* @param fromXType Specifies how fromXValue should be interpreted. One of
* Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
* Animation.RELATIVE_TO_PARENT.
* @param fromXValue Change in X coordinate to apply at the start of the
* animation. This value can either be an absolute number if fromXType
* is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
* @param toXType Specifies how toXValue should be interpreted. One of
* Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
* Animation.RELATIVE_TO_PARENT.
* @param toXValue Change in X coordinate to apply at the end of the
* animation. This value can either be an absolute number if toXType
* is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
* @param fromYType Specifies how fromYValue should be interpreted. One of
* Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
* Animation.RELATIVE_TO_PARENT.
* @param fromYValue Change in Y coordinate to apply at the start of the
* animation. This value can either be an absolute number if fromYType
* is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
* @param toYType Specifies how toYValue should be interpreted. One of
* Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
* Animation.RELATIVE_TO_PARENT.
* @param toYValue Change in Y coordinate to apply at the end of the
* animation. This value can either be an absolute number if toYType
* is ABSOLUTE, or a percentage (where 1.0 is 100%) otherwise.
*/
public TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue,
int fromYType, float fromYValue, int toYType, float toYValue) { mFromXValue = fromXValue;
mToXValue = toXValue;
mFromYValue = fromYValue;
mToYValue = toYValue; mFromXType = fromXType;
mToXType = toXType;
mFromYType = fromYType;
mToYType = toYType;
} @Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
float dx = mFromXDelta;
float dy = mFromYDelta;
if (mFromXDelta != mToXDelta) {
dx = mFromXDelta + ((mToXDelta - mFromXDelta) * interpolatedTime);
}
if (mFromYDelta != mToYDelta) {
dy = mFromYDelta + ((mToYDelta - mFromYDelta) * interpolatedTime);
}
t.getMatrix().setTranslate(dx, dy);
} @Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mFromXDelta = resolveSize(mFromXType, mFromXValue, width, parentWidth);
mToXDelta = resolveSize(mToXType, mToXValue, width, parentWidth);
mFromYDelta = resolveSize(mFromYType, mFromYValue, height, parentHeight);
mToYDelta = resolveSize(mToYType, mToYValue, height, parentHeight);
}
能够看到实际上重写了两个方法:initialize和applyTransformation
/**
* Initialize this animation with the dimensions of the object being
* animated as well as the objects parents. (This is to support animation
* sizes being specifed relative to these dimensions.)
*
* <p>Objects that interpret Animations should call this method when
* the sizes of the object being animated and its parent are known, and
* before calling {@link #getTransformation}.
*
*
* @param width Width of the object being animated
* @param height Height of the object being animated
* @param parentWidth Width of the animated object's parent
* @param parentHeight Height of the animated object's parent
*/
public void initialize(int width, int height, int parentWidth, int parentHeight) {
reset();
mInitialized = true;
}
/**
* Helper for getTransformation. Subclasses should implement this to apply
* their transforms given an interpolation value. Implementations of this
* method should always replace the specified Transformation or document
* they are doing otherwise.
*
* @param interpolatedTime The value of the normalized time (0.0 to 1.0)
* after it has been run through the interpolation function.
* @param t The Transofrmation object to fill in with the current
* transforms.
*/
protected void applyTransformation(float interpolatedTime, Transformation t) {
}
从initialize方法的凝视上看,这种方法的主要作用是:初始化对象的尺寸以及父容器尺寸(为了确定和父容器的相对位置)。
从applyTransformation方法的凝视上看,这种方法应该被实现,这种方法给出了一个interpolation值,并帮助获得Transformation对象,应该自己设置transformation对象来实现自己的动画效果。
好吧,基于以上研究。我们试着来重写一个Animation
package com.example.testanimation; import android.graphics.Camera;
import android.graphics.Matrix;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.Transformation; /**
* 自己定义动画
* @author 阳光小强
*
*/
public class MyAnimation extends Animation{ private float centerX;
private float centerY;
private int duration;
private Camera camera = new Camera();
public MyAnimation(float x, float y, int duration){
this.centerX = x;
this.centerY = y;
this.duration = duration;
} @Override
public void initialize(int width, int height, int parentWidth,
int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight); setDuration(duration); setFillAfter(true); setInterpolator(new LinearInterpolator());
} @Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
camera.save();
camera.translate(100f - 100f * interpolatedTime, 150f * interpolatedTime -150, 80f - 80f * interpolatedTime);
camera.rotateY(360 * interpolatedTime);
camera.rotateX(360 * interpolatedTime);
Matrix matrix = t.getMatrix();
camera.getMatrix(matrix);
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
camera.restore();
}
}
代码解释:
1、setDuration(duration):设置动画时间
2、setFillAfter(true):设置动画结束后保持。假设设为false则动画结束后回到原来状态。
3、setInterpolator(new LinearInterpolator()):Interpolater实际上是控制补间动画的插入帧的频率的,所以就会有加速、减速、匀速动画。
4、Camera:一个空间变换工具。相似于Matrix。提供了各种变换方法,如上面的translate和rotateY等。
5、Matrix:一个三维的矩阵变换函数。
6、camera.getMatrix(matrix):计算当前的矩阵变换,并将其拷贝到矩阵matrix中。
7、matrix.preTranslate :运行矩阵指定的转换。
8、matrix.postTranslate:运行矩阵指定的转换(后面两个方法怎么转换,有什么差别,这就是数学知识了。一两句也说不清)。
Android中的动画具体解释系列【3】——自己定义动画研究的更多相关文章
- Android中的动画具体解释系列【4】——Activity之间切换动画
前面介绍了Android中的逐帧动画和补间动画,并实现了简单的自己定义动画.这一篇我们来看看怎样将Android中的动画运用到实际开发中的一个场景--Activity之间跳转动画. 一.定义动画资源 ...
- Android中时间戳的详细解释
Android中时间戳的详细解释: (1).定义: 时间戳就是根据当前系统时间生成的一组随机数字. (2).作用: 作为对数据唯一性的一种判断依据.避免了重复修改数据所带来的错误! (3).应用: ( ...
- Android中的动画具体解释系列【2】——飞舞的蝴蝶
这一篇来使用逐帧动画和补间动画来实现一个小样例,首先我们来看看Android中的补间动画. Android中使用Animation代表抽象的动画类,该类包含以下几个子类: AlphaAnimation ...
- Android中AsyncTask使用具体解释
在Android中我们能够通过Thread+Handler实现多线程通信.一种经典的使用场景是:在新线程中进行耗时操作.当任务完毕后通过Handler向主线程发送Message.这样主线程的Handl ...
- Android中的动画具体解释系列【1】——逐帧动画
逐帧动画事实上非常easy,以下我们来看一个样例: <?xml version="1.0" encoding="utf-8"?> <anima ...
- Android中Activity切换时共享视图元素的切换动画(5.0以上)
同一时候公布在我的博客 点此进入 背景 说来这个的背景很easy,常常在使用图片列表的时候就会想,假设"列表中的图片放大到整个屏幕"作为 Activity 的补间动画.就很完美了. ...
- android中OnItemClickListener的参数解释
@Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) {} ...
- Android中SharedPreferences函数具体解释
Android平台提供了一个SharedPreferences类,它是一个轻量级应用程序内部轻量级的存储方案,特别适合用于保存软件配置參数,比方boolean,int,float,long,Strin ...
- [转]android中drawable资源的解释及例子
原文链接: http://blog.csdn.net/wode_dream/article/details/38584693 文章中的内容参考Dev Guide中的Drawable R ...
随机推荐
- vue ---webpack 打包上线
先来描述一下期间遇到的问题有哪些: 1.打包后将 dist 文件夹和 index.html 放到 tomcat,在浏览器中访问时,出现空白页,f12 提示 404. 2.打包好的静态资源均是绝对路径 ...
- vue中v-for的用法以及参数的作用
<template> <div> <div class="content clearfix" v-on:click="goorderingD ...
- 3/21 Django框架 模板路径及模板过滤器 1.模板路径查找
3/21 Django框架 模板路径及模板过滤器 1.模板路径查找 先找settings.py里的TEMPLATES列表下的DIRS路径.如果APP_DIRS为True,还会到注册了的APP文件夹下依 ...
- Node.js笔记(九)Nodejs与shell
众所周知.Nodejs是单进程异步执行的.但不光是单进程,Nodejs也提供了多进程方面的支持 其创始人应该还是比較重视这一块的,最有力的证据就是child_process是Nodejs核心模块之中的 ...
- android:一个Open键引发的问题!!
1.问题简单介绍 首先描写叙述一下问题.当我们安装完APP的时候,界面会显示两个button,一个完毕键,一个Open键,点击Open键之后.进入应用.此时.我们点击HOME键.程序将会后台.然后再点 ...
- 感谢党,软考过了。系统集成项目管理project师
人品爆发了,刚用干巴巴的日语做完2小时的设计说明,回到家一查,人品爆发了.软考竟然过了. 绝对是评卷老师给人品啊!真想请他吃顿饭. 系统集成项目管理project师 64 53 幸运飞过! 今天真是 ...
- Accelerated C++:通过演示样例进行编程实践——练习解答(第9章)
我的Github地址:https://github.com/lanbeilyj/Accerlerated-C-plus-plus 9-0. Compile, execute, and test the ...
- HTML基础第七讲---框架
转自:https://i.cnblogs.com/posts?categoryid=1121494 框架(Frame)也就是所谓的分割窗口.分割画面.框窗效果(还真是五花八门),这个技巧在运用上问题比 ...
- js面向对象1----了解构造函数
一.构造函数与实例的区别 1 构造函数 构造函数主要是一种用于生成对象的饼干模具,这些对象具有默认属性和属性方法,它可以创建多个共享特定特性和行为的对象. 构造函数只是一个函数,但当函数遇到了ne ...
- time and datetime
一.简述 我们在写代码的过程经常遇到时间模块,如果我们以后需要根据时间去筛选信息的话,那用户会更大,所以今天就来讲讲时间的两大模块:time & datetime 二.time模块 1.tim ...