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 ...
随机推荐
- 1.3 Quick Start中 Step 3: Create a topic官网剖析(博主推荐)
不多说,直接上干货! 一切来源于官网 http://kafka.apache.org/documentation/ Step 3: Create a topic Step 3: 创建一个主题(topi ...
- mysql-cacti-templates-1.1.2.tar.gz 免费下载 cacti MySQL添加监控
cacti MySQL添加监控 1. 安装监控插件 wget http://mysql-cacti-templates.googlecode.com/files/mysql-cacti-templat ...
- drawable-图片绘制
首先看一下,下端代码 private Bitmap createSelectedChip(RecipientEntry contact, TextPaint paint) { int height = ...
- js课程 6-15 js简单弹力球如何实现
js课程 6-15 js简单弹力球如何实现 一.总结 一句话总结:a.通过document的documentElement属性获取可是区域的高: b.通过增值变为负的实现到底部后反弹 1.docume ...
- solr索引创建流程
solr索引创建流程: 分词组件Tokenizer 分词组件(Tokenizer)会做以下几件事情(这个过程称为:Tokenize),处理得到的结果是词汇单元(Token). 1.将文档分成一个一个单 ...
- FFmpegh.264解码
- (int)DecodeH264Frames: (unsigned char*)inputBuffer withLength:(int)aLength { ; ; av_init_packet(&a ...
- 洛谷 P1644 跳马问题
P1644 跳马问题 题目背景 在爱与愁的故事第一弹第三章出来前先练练四道基本的回溯/搜索题吧…… 题目描述 中国象棋半张棋盘如图1所示.马自左下角(0,0)向右上角(m,n)跳.规定只能往右跳,不准 ...
- ajax+客户端与服务器端的交互
一. AJAX 原生JS var xhr=new XMLHttpRequest(); xhr.open("GET","[请求地址]",false); xhr.o ...
- (转)oracle常用的数据字典
一.oracle数据字典主要由以下几种视图构成: .user视图 以user_为前缀,用来记录用户对象的信息 .all视图 以all_为前缀,用来记录用户对象的信息及被授权访问的对象信息 .dba视图 ...
- 【2017 ACM-ICPC 亚洲区(西安赛区)网络赛 B】
[链接]h在这里写链接 [题意] 一个硬币正面朝上的概率为q/p; 抛k次,问你偶数次朝上的概率为多少. [题解] [错的次数] 0 [反思] 在这了写反思 [代码] #include <bit ...