属性动画,就是通过控制对象中的属性值产生的动画。属性动画是目前最高级的2D动画系统。

在API Level 11中添加。Property Animation号称能控制一切对象的动画,包括可见的和不可见的。

但是,日常开发中我们一般都是对UI定制动画。

使用ObjectAnimator

ObjectAnimator是其中比较容易使用的一个动画类,它继承自ValueAnimator,

说比较容易使用是因为它在动画启动后自动监视属性值的变化并把值赋给对象属性,

而ValueAnimator则只监视属性值的变化,但不会自动在属性中应用该值,因此我们需要手动应用这些值。

代码:

//创建一个水平移动的动画对象,从位置0到300平移
final ObjectAnimator translation = ObjectAnimator.ofFloat(tv, "translationX", 0f, 300f);
translation.setDuration(1500);

只需两行就可以创建一个简单可运行的移动动画。

当然还有其他setxxx()方法可以控制动画的高级行为。

例如:添加一个插值器等

translation.setInterpolator(new AccelerateDecelerateInterpolator());

运行效果:

使用ValueAnimator

ValueAnimtor动画的创建基本上和ObjectAnimator一样,只是我们需要手动应用属性值

代码:

final ValueAnimator translation = ValueAnimator.ofFloat(0f, 300f);
translation.setDuration(1500);

有点不一样的是在创建对象的时候,ValueAnimator无需指定属性名称

只需指定动画的执行范围。

上面我们已经说了,ValueAniamtor不会自动应用属性值,因此我们需要添加一个动画监听器

translation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
{
@Override
public void onAnimationUpdate(ValueAnimator animation)
{
tv.setTranslationX((float) animation.getAnimatedValue());
}
});

tv是我们需要执行动画的对象,这里是一个TextView对象。

要使tv对象的动画执行,我们就要在监听器中使用对应setxxx方法更新tv的属性值,

而这些值我们可以使用animation对象的getAnimatedValue方法获得。

使用动画监听器执行不同的任务

通过监听器我们可以在动画的不同状态执行不同的任务

translation.addListener(new Animator.AnimatorListener()
{
@Override
public void onAnimationStart(Animator animation)
{ } @Override
public void onAnimationCancel(Animator animation)
{ } @Override
public void onAnimationRepeat(Animator animation)
{ } @Override
public void onAnimationEnd(Animator animation)
{ }
});

例如:我们可以在前一个动画执行完毕之后执行另一个动画

translation.addListener(new Animator.AnimatorListener()
{
@Override
public void onAnimationStart(Animator animation)
{ } @Override
public void onAnimationCancel(Animator animation)
{ } @Override
public void onAnimationRepeat(Animator animation)
{ } @Override
public void onAnimationEnd(Animator animation)
{
ObjectAnimator rotation = ObjectAnimator.ofFloat(tv, "rotation", 0f, 360f);
rotation.setDuration(1500);
rotation.start();
}
});

执行效果:

使用PropertyValuesHolder控制多个对象属性

例如我们对某个对象进行缩放控制的时候,就需要同时改变对象的x轴和y轴的值

这个时候我们就可以使用ObjectAnimator的ofPropertyValuesHolder()方法配合PropertyValuesHolder对象

//把按钮放大1.5倍
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("scaleX", 1f, 1.5f);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleY", 1f, 1.5f);
final ObjectAnimator scale = ObjectAnimator.ofPropertyValuesHolder(btnStart, pvhX, pvhY); final ValueAnimator translation = ValueAnimator.ofFloat(0f, 300f);
translation.setDuration(1500);
btnStart.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v)
{
//执行放大动画
scale.start();
translation.start();
}
});

运行效果:

使用Keyframe对象控制多属性动画

Keyframe对象对多属性动画的控制更加灵活,因为我们可以更好地控制每个时间段执行的动画距离

        Keyframe keyframe0 = Keyframe.ofFloat(0f, 0);
Keyframe keyframe1 = keyframe.ofFloat(.3f, 100);
Keyframe keyframe2 = keyframe.ofFloat(.4f, 200);
Keyframe keyframe3 = keyframe.ofFloat(1f, 200);
        PropertyValuesHolder pvhM = PropertyValuesHolder.ofKeyframe("translationX", keyframe0,keyframe1, keyframe2,keyframe3);
final ObjectAnimator trans = ObjectAnimator.ofPropertyValuesHolder(tv, pvhM);
trans.setDuration(1500);
final ValueAnimator translation = ValueAnimator.ofFloat(0f, 300f);
translation.setDuration(1500);
btnStart.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v)
{
//执行放大动画
scale.start();
trans.start();
//translation.start();
}
});

代码分析:

每个keyframe变量第一个参数执行总时间0%~100%,0表示动画未执行,1代码动画执行完毕

keyframe0代表动画在0%时的位置

keyframe1代表动画在30%时所处的位置

keyframe2代表动画在最后一个时间段所处的位置

keyframe3代表在200个单位距离时动画完成已经停止,加上这一行是为了动画停止后对象不会消失

运行效果:

上面的图片虽然不是看得很清楚,但是可以看见在最后一段时间动画突然加快。

原因是我们在定义最后一个keyframe的时候是用10%的时间走100个单位距离,

即它要在最短的时间走最多的距离,所以它必须加快速度才能完成这个任务。

不加keyframe3时的运行效果:

完整代码:

package com.whathecode.propertyanimation;

import android.animation.Animator;
import android.animation.Keyframe;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView; public class MainActivity extends ActionBarActivity
{ @Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); final TextView tv = (TextView) findViewById(R.id.tv); Button btnStart = (Button) findViewById(R.id.start);
/* //创建一个水平移动的动画对象,从位置0到300平移
final ObjectAnimator translation = ObjectAnimator.ofFloat(tv, "translationX", 0f, 300f);
translation.setDuration(1500);
*/ //把按钮放大1.5倍
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("scaleX", 1f, 1.5f);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleY", 1f, 1.5f);
final ObjectAnimator scale = ObjectAnimator.ofPropertyValuesHolder(btnStart, pvhX, pvhY); Keyframe keyframe0 = Keyframe.ofFloat(0f, 0);
        Keyframe keyframe1 = keyframe.ofFloat(.3f, 100);
Keyframe keyframe2 = keyframe.ofFloat(.4f, 200);
Keyframe keyframe3 = keyframe.ofFloat(1f, 200);
PropertyValuesHolder pvhM = PropertyValuesHolder.ofKeyframe("translationX", keyframe0,keyframe1, keyframe2,keyframe3);
final ObjectAnimator trans = ObjectAnimator.ofPropertyValuesHolder(tv, pvhM);
trans.setDuration(1500);
final ValueAnimator translation = ValueAnimator.ofFloat(0f, 300f);
translation.setDuration(1500);
btnStart.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v)
{
//执行放大动画
scale.start();
trans.start();
//translation.start();
}
}); translation.addListener(new Animator.AnimatorListener()
{
@Override
public void onAnimationStart(Animator animation)
{ } @Override
public void onAnimationCancel(Animator animation)
{ } @Override
public void onAnimationRepeat(Animator animation)
{ } @Override
public void onAnimationEnd(Animator animation)
{
ObjectAnimator rotation = ObjectAnimator.ofFloat(tv, "rotation", 0f, 360f);
rotation.setDuration(1500);
rotation.start();
}
}); translation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
{
@Override
public void onAnimationUpdate(ValueAnimator animation)
{
tv.setTranslationX((float) animation.getAnimatedValue());
}
});
}
}

使用属性动画 — Property Animation的更多相关文章

  1. Android动画主要包含补间动画(Tween)View Animation、帧动画(Frame)Drawable Animation、以及属性动画Property Animation

    程序运行效果图: Android动画主要包含补间动画(Tween)View Animation.帧动画(Frame)Drawable Animation.以及属性动画Property Animatio ...

  2. 使用属性动画 — Property Animation

    属性动画,就是通过控制对象中的属性值产生的动画.属性动画是目前最高级的2D动画系统. 在API Level 11中添加.Property Animation号称能控制一切对象的动画,包括可见的和不可见 ...

  3. Android 动画——属性动画Property Animation

    Android在3.0之前只提供了两种动画:View Animation .Drawable Animation .也就是我们在<Android 动画——Frame Animation与Twee ...

  4. 属性动画(Property Animation)

    属性动画系统是一个强大的可以绘制任意事物.你可以定义改变物体属性的动画,不管它是不是在屏幕上.属性动画随着时间的推移去改变物体的属性.如果要让某个事物动起来,你只需指定该事物的某个属性,如物体的坐标. ...

  5. 属性动画Property Animation

    ViewPropertyAnimation 使用方式:View.animate() 后跟 translationX() 等方法,动画会自动执行. 注意translationX实现是调用对应的set方法 ...

  6. Android(java)学习笔记263:Android下的属性动画(Property Animation)

    1. 属性动画(Property Animation)引入: 在手机上去实现一些动画效果算是件比较炫酷的事情,因此Android系统在一开始的时候就给我们提供了两种实现动画效果的方式,逐帧动画(fra ...

  7. Android(java)学习笔记207:Android下的属性动画(Property Animation)

    1. 属性动画(Property Animation)引入: 在手机上去实现一些动画效果算是件比较炫酷的事情,因此Android系统在一开始的时候就给我们提供了两种实现动画效果的方式,逐帧动画(fra ...

  8. Android动画:模拟开关按钮点击打开动画(属性动画之平移动画)

    在Android里面,一些炫酷的动画确实是很吸引人的地方,让然看了就赏心悦目,一个好看的动画可能会提高用户对软件的使用率.另外说到动画,在Android里面支持3种动画: 逐帧动画(Frame Ani ...

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

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

随机推荐

  1. Android dialog 全屏

    Android中让Dialog全屏: 一.在style中定义样式: <?xml version="1.0" encoding="utf-8"?> & ...

  2. Think PHP递归获取所有的子分类的ID (删除当前及子分类)

    递归获取所有的子分类的ID: //递归获取所有的子分类的ID function get_all_child($array,$id){ $arr = array(); foreach($array as ...

  3. 170630、springboot编程之普通类中调用spring管理的bean对象

    我们知道如果我们要在一个类使用spring提供的bean对象,我们需要把这个类注入到spring容器中,交给spring容器进行管理,但是在实际当中,我们往往会碰到在一个普通的Java类中,想直接使用 ...

  4. poj 2723 Get Luffy Out 2-SAT

    两个钥匙a,b是一对,隐含矛盾a->!b.b->!a 一个门上的两个钥匙a,b,隐含矛盾!a->b,!b->a(看数据不大,我是直接枚举水的,要打开当前门,没选a的话就一定要选 ...

  5. 006-spring cache-缓存实现-01-原生实现

    一.原生实现 1.1.pom <!-- 缓存 --> <dependency> <groupId>org.springframework.boot</grou ...

  6. git-【九】基本常用命令

    mkdir:         XX (创建一个空目录 XX指目录名) pwd:          显示当前目录的路径. git init          把当前的目录变成可以管理的git仓库,生成隐 ...

  7. JAVA 对象内存结构

    JAVA对象内存结构 HotSpot虚拟机中,对象在内存中存储的布局可以分为三块区域:对象头(Header).实例数据(Instance Data)和对齐填充(Padding). 对象头 markWo ...

  8. ffmpeg应用笔记

    官网 http://ffmpeg.org/ 应用手册 http://ffmpeg.org/documentation.html 雷霄骅专栏 https://blog.csdn.net/leixiaoh ...

  9. glassfish3新建domain

    下载路径:http://download.oracle.com/glassfish/3.1.2.2/release/index.html .zip (解压缩)cd /glassfish3/glassf ...

  10. Alpine Linux配置使用技巧【一个只有5M的操作系统(转)】

    Alpine Linux是一个面向安全应用的轻量级Linux发行版.它采用了musl libc和busybox以减小系统的体积和运行时资源消耗,同时还提供了自己的包管理工具apk. Alpine Li ...