转载请注明出处:http://blog.csdn.net/h28496/44338669

属性动画的原理

通过不断的设置一个View的属性让其出现动画效果。比如,不断地设置一个Button的x值。这个button就会在y轴上运动。

假设学过flash或者其它动画制作的话。应该能理解“补间动画”的意思。属性动画类似于属性上的补间动画。

设置一个View的初始值和结束值,属性动画会随着时间的变化,逐渐地把View的属性从初始值变化到结束值。

实现属性动画的条件

由属性动画的原理可知,要实如今某个方面的动画。首先这个View得有这个属性。即,要有 set属性名() 和 get属性名()方法。

比如:setWidth(), getWidth()。

注意:button自带的getWidth() 和 setWidth()在这里是没有效果的。回忆一下在代码中设置一个button的宽度是怎么设置的?

在代码中设置宽度:

button.getLayoutParams().width = 100;

它相应于xml文件里的是

android:layout_width

而不是

android:width

至于width有什么用,我感觉没什么用……看过其它大牛写的博客。也是不太清楚android:width有什么用。

一个简单的样例

效果:点击了Button之后按x轴翻转。

Button的布局文件非常普通。不贴了。

	public void onClick(View view) {
ObjectAnimator
.ofFloat(view, "rotationX", 0f, 360f)
.setDuration(1000)
.start();
}

解释一下:由于Button这个类存在 setRotationX(float p)这种方法。所以第三行的第二个參数 “rotationX” 是有效的。

假设写的是一个不存在的參数,或者设置的參数和画面无关,那么画面是没有动画的。

另外,因为setRotationX(float p)的參数类型是float型的,所以第三行用的是 ofFloat(...) 而不是 ofInt(...)或者其它。

setDuration(int p)是动画的时长。单位毫秒。

我在看任玉刚大牛写的博客时他写道,假设没有set属性名()这种方法会导致程序崩溃。但我实測时没有崩溃,仅仅是在logcat报了一条错误,程序继续执行。

假设条件不满足怎么办

假设你想给某个View设置一个动画,可是它没有相应的设置属性的方法怎么办?比如:

我们想给button设置一个宽度逐渐变宽的动画,可是button的setWidth()不能设置显示宽度。

解决的办法:

① 加上set属性()、get属性()方法;(除非是你自己定义的控件,否则一般没有权限这么做,以下就不讨论这样的情况了)

② 用一个类去包装原始的对象。间接的提供get、set方法;

③ 採用ValueAnimation获得每个时刻的属性值,然后通过AnimatorUpdateListener监听器依据获得的属性值设置View的状态。

包装原始对象

用这样的方式为一个不存在某种方法的类加入方法非经常见。考虑到多态,通常包装比继承要好得多。

以下是用MyView包装View的样例:

class MyView{
View view; public MyView(View view){
this.view = view;
} public int getWidth(){
return view.getLayoutParams().width;
} public void setWidth(int width){
this.view.getLayoutParams().width = width;
this.view.requestLayout(); // 这句话用来又一次设置view的位置
}
}

有了包装类。我们就来实现一个让Button(它是继承自View的)宽度变宽的动画吧。

效果:在300毫秒内,view的宽度先变成4倍,再恢复到原来的样子。

	public void onClick(View v) {
MyView view = new MyView(v);// 先包装一下
int startWidth = v.getWidth();
ObjectAnimator.ofInt(view, "width", startWidth, startWidth * 4, startWidth)
.setDuration(300)
.start();
}

使用ValueAnimator和AnimatorUpdateListener自己实现

效果:在一秒的时间内,view从y = 0,移动到 y  = 500的地方。

	public void onClick(final View view){
final ValueAnimator anim = ValueAnimator.ofFloat(0, 500);
anim.setDuration(1000);
anim.start(); anim.addUpdateListener(new AnimatorUpdateListener() { @Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (Float) animation.getAnimatedValue();
view.setTranslationY(value);
}
});
}

先定义一个值动画(ValueAnimator,中文名个人是意译的)。从名称能够看出,它仅仅是一个“值”的变化,并不涉及到详细的视图。

然后再对这个值动画设置一个监听器。每次值有变化的时候。都将这个值应用到视图的属性上去。

比如。值每变化一次,都要又一次设置一下位置。

尽管看起来麻烦了一点。但灵活性更高了。

多个动画同一时候运行

上面的三个样例中。动画都是单独一个。假设我想要在它移动的同一时候还要改变它的透明度怎么办呢?

和上面的类似。能够利用AnimatorUpdateListener实现。

② 利用PropertyValuesHolder实现;

③ 利用AnimatorSet实现。

利用AnimatorUpdateListener实现

上一个样例中仅仅设置了视图的位置,但实际上能够同一时候将视图的多个属性设置为那个值。

仅仅需多加几个.set属性()。

这里为了避免反复,不使用ValueAnimator,而是使用ObjectAnimator。

效果:被点击的视图在1秒内。先变小同一时候颜色减淡到无,之后再恢复到原状。(建议使用一个ImageView而不是Button,效果更好)

	public void onClick(final View v){
ObjectAnimator anim = ObjectAnimator.ofFloat(v, "", 1, 0, 1)
.setDuration(1000);
anim.start(); anim.addUpdateListener(new AnimatorUpdateListener() { @Override
public void onAnimationUpdate(ValueAnimator animation) {
float currentValue = (Float) animation.getAnimatedValue();
v.setScaleX(currentValue);
v.setScaleY(currentValue);
v.setAlpha(currentValue);
}
});
}

ObjectAnimator和ValueAnimator一样,也是能够加入监听器的。

利用PropertyValuesHolder实现

这样的实现方式代码非常简洁,一看便懂。

效果:被点击的视图在1秒内,先变小、颜色减淡到无,之后再恢复到原状,同一时候整个过程视图旋转了360度。(建议使用一个ImageView而不是Button,效果更好)

	public void onClick(View view){
PropertyValuesHolder x = PropertyValuesHolder.ofFloat("scaleX", 1, 0, 1);
PropertyValuesHolder y = PropertyValuesHolder.ofFloat("scaleY", 1, 0, 1);
PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1, 0, 1);
PropertyValuesHolder rotation = PropertyValuesHolder.ofFloat("rotation", 0, 360); ObjectAnimator.ofPropertyValuesHolder(view, x, y, alpha, rotation).setDuration(1000).start();
}

利用AnimatorSet实现

从名字能够看出。这是一个动画的集合。AnimatorSet能够让多个动画同一时候执行、先后执行

同一时候执行

效果:被点击的视图在X方向变大的同一时候。Y方向也变大。之后又同一时候缩小(建议使用一个ImageView而不是Button,效果更好)

	public void togetherRun(View view){
// 感觉和PropertyValuesHolder差点儿相同
ObjectAnimator x = ObjectAnimator.ofFloat(view, "scaleX", 1, 2, 1);
ObjectAnimator y = ObjectAnimator.ofFloat(view, "scaleY", 1, 2, 1); AnimatorSet animSet = new AnimatorSet();
animSet.setDuration(1000); animSet.playTogether(x, y);
animSet.start();
}

playTogether(Animator... items)能够让多个动画同一时候运行。除此之外。还有playWidth(Animator item)能够让两个动画同一时候运行。

先后执行

效果:被点击的视图在X、y方向变大又缩小,之后再平移到右边并返回(建议使用一个ImageView而不是Button。效果更好)

	public void playAfter(View view){
ObjectAnimator scaleX = ObjectAnimator.ofFloat(ball, "scaleX", 1, 2, 1);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(ball, "scaleY", 1, 2, 1); ObjectAnimator x = ObjectAnimator.ofFloat(ball, "x", ball.getX(), ball.getX() + 200, ball.getX()); AnimatorSet animSet = new AnimatorSet();
// 支持链式编程
animSet.play(scaleX).with(scaleY);
animSet.play(x).after(scaleY);
animSet.setDuration(1000);
animSet.start();
}
}

在先后运行的时候,还能够调用animSet.play(x).after(延迟时间); 使得下一个动画延迟播放。

这里使用的是animSet.play(x).after(scaleY); 即在还有一个动画播放完之后再播放,也能够使用

animSet.play(x).before(anim1); 

让一个动画在还有一个动画播放前播放。

怎样监听动画的结束

animation有三种监听器:

① AnimatorUpdateListener(监听在动画运行过程中的数据或其他情况)

② AnimatorListener(监听动画的‘生命周期’)

③ AnimatorPauseListener(监听动画的暂停与恢复)

有时我们须要在动画结束之后做点事。比如:在点击一个button结束后跳转到还有一个Activity。

这时我们仅仅需让动画加入一个AnimatorListener监听器。

anim.addListener(new AnimatorListener() {

			@Override
public void onAnimationStart(Animator animation) {
// TODO Auto-generated method stub } @Override
public void onAnimationRepeat(Animator animation) {
// TODO Auto-generated method stub } @Override
public void onAnimationEnd(Animator animation) {
// TODO Auto-generated method stub
// 在这里加入动画结束后要做的事
} @Override
public void onAnimationCancel(Animator animation) {
// TODO Auto-generated method stub }
});

如上所看到的,动画共同拥有四个状态。有时我们并不须要实现全部的方法,仅仅须要当中一个状态就能够了。那我们能够使用AnimatorListenerAdapter。它继承了AnimatorListener接口。

空实现了全部方法。

演示样例:

anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
view.setY(startY);
}
});

安卓的属性动画大致就讲完了。

參考资料:

http://blog.csdn.net/lmj623565791/article/details/38067475

http://blog.csdn.net/singwhatiwanna/article/details/17841165

【Android】属性动画的更多相关文章

  1. Android属性动画

    这几天看郭神的博客 Android属性动画完全解析(上),初识属性动画的基本用法之后,我自己突然想实现一种动画功能,就是我们在携程网.阿里旅行等等手机APP端买火车票的时候,看到有选择城市,那么就有出 ...

  2. 【转】android 属性动画之 ObjectAnimator

    原文网址:http://blog.csdn.net/feiduclear_up/article/details/39255083 前面一篇博客讲解了 android 简单动画之 animtion,这里 ...

  3. Android属性动画之ValueAnimation

    ValueAnimation是ObjectAnimation类的父类,经过前几天的介绍,相信大家对ObjectAnimation有了 一定的认识,今天就为大家最后介绍一下ValueAnimation, ...

  4. Android属性动画完全解析(下)

    转载:http://blog.csdn.net/guolin_blog/article/details/44171115 大家好,欢迎继续回到Android属性动画完全解析.在上一篇文章当中我们学习了 ...

  5. Android属性动画完全解析(上),初识属性动画的基本用法

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/43536355 在手机上去实现一些动画效果算是件比较炫酷的事情,因此Android系 ...

  6. Android属性动画完全解析(中)

    转载:http://blog.csdn.net/guolin_blog/article/details/43536355 大家好,在上一篇文章当中,我们学习了Android属性动画的基本用法,当然也是 ...

  7. Android属性动画完全解析(上)

    Android属性动画完全解析(上) 转载:http://blog.csdn.net/guolin_blog/article/details/43536355 在手机上去实现一些动画效果算是件比较炫酷 ...

  8. Android 属性动画(Property Animation) 全然解析 (下)

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38092093 上一篇Android 属性动画(Property Animatio ...

  9. Android 属性动画 源码解析 深入了解其内部实现

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/42056859,本文出自:[张鸿洋的博客] 我参加了博客之星评选,如果你喜欢我的博 ...

  10. 用Android属性动画实现和演示迪士尼动画基本原则

    本文将介绍在Android平台上实现和演示迪士尼动画基本准则. 项目开源,GitHub: https://github.com/vhow/animation 说明: 演示动画原则的想法源自 Anima ...

随机推荐

  1. Xcode 静态库调试策略

    Xcode 静态库调试策略  (已经有现成的工程和静态库源码)    ***** 为安全期间建议备份一下静态库 Step1: 下载最新的工程[工程中有所要测试的静态库和头文件需要删除]: Step2: ...

  2. [Swust OJ 1026]--Egg pain's hzf

      题目链接:http://acm.swust.edu.cn/problem/1026/     Time limit(ms): 3000 Memory limit(kb): 65535   hzf ...

  3. Get与POST的理解

    针对GET& POST的掌握可以说是迷迷糊糊的,今天特意拿出来好好整理一下,便于掌握理解. 在服务器端都有一个用来标识资源位置的符号,被称为统一资源标识(URL). URI有两种形式.分别为U ...

  4. ZOJ 2856 Happy Life 暴力求解

    因为是Special Judge 的题目,只要输出正确答案即可,不唯一 暴力力求解, 只要每次改变 happiness 值为负的人的符号即可. 如果计算出当前人的 happiness 值为负,那么将其 ...

  5. Windows的公共控件窗口类列表

    The following window class names are provided by the common control library: ANIMATE_CLASS Creates a ...

  6. Python 2.7 学习笔记 基本知识

    python是一种解释型的.面向对象的.带有动态语义的高级程序设计语言.本文介绍下python的基本知识. 一.安装 各种操作系统有自己的安装方法,linux系统一般都自带了python的环境.这里不 ...

  7. zk mysql 主从自动切换

    zookeeper测试: DBI 版本: /DBI-1.616# zjtest7-redis:/root/DBD-mysql-4.031# perl Makefile.PL Can't exec &q ...

  8. 基于visual Studio2013解决算法导论之019栈实现(基于数组)

     题目 用数组实现栈 解决代码及点评 #include <stdio.h> #include <stdlib.h> #include <time.h> #in ...

  9. CMAKE的使用

    CMAKE的使用 Version 1.0 2009-3-18 一.      基本使用 安装:下载二进制包后可直接解压使用 从源码安装则执行命令:./bootstrap; make; make ins ...

  10. 飞翔(LIS变形)

    飞翔 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 鹰最骄傲的就是翱翔,但是鹰们互相都很嫉妒别的鹰比自己飞的快,更嫉妒其他的鹰比自己飞行的有技巧.于是,他们决定举办一场 ...