Android进阶——属性动画Property Animation详解(一)

引言

前一篇文章Android入门——补间动画和帧动画应用小结总结了补间动画和帧动画及一些相关类的应用,基本可以掌握简单的缩放、旋转、透明度变化、平移的动画效果,但是需要实现更复杂的动画效果时,比如说希望View的切换动画、Layout的切换动画、3D旋转动画等等,这些View Animation都无法做到。此时Property Animation应运而生,这篇主要总结下属性动画的相关知识点。

一、Property Animation属性动画概述

属性动画,在我最先接触到Android 1.5时还没有这个动画系统,直到Android 3.0中才引进的(在3.0之前的系统中,可通过NineOldAndroids项目使用Property Animation)。官方文档是这样介绍他的:该属性动画系统是一个强大的框架,几乎可以为任何对象设置动画效果,可以定义随时间而改变任何对象属性的动画,无论它是否已经绘制到屏幕。在指定的时间长度值,改变的是对象的实际属性的(一个字段中的对象)值。简而言之,Property Animation就是,由动画的执行类(Animator系)来设置动画操作的对象的属性、持续时间,开始和结束的属性值,时间差值等,然后系统会根据设置的参数动态地改变对象的属性从而形成的一种动画效果。

二、Property Animation动画过程

接下来引用下官方文档的例子说明下(Ps:Google的官方文档已经说得很好了,可以说是最好的学习教材,当然你得耐心看英文)。

第一个例子是以持续时间为40ms且匀速变化的动画,其中每10ms刷新一帧(目的是通过10个像素水平移动),请注意把x看作这个对象的实际属性的话,这个x也是随着动画的进行一直在改变的。

第二个可以看到,这是非线性变化的动画(通过改变属性值的方法,即设置不同的interpolation,在下图中运动速度先逐渐增大再逐渐减小),也是在40ms的时间移动了40个像素,x这个属性也是随着动画的进行不断在改变的。

1、属性动画的监听器

属性动画的基类Animator里封装了两个内部监听接口:Animator.AnimatorListener『onAnimationCancel(Animator animation)、onAnimationEnd(Animator animation)、onAnimationRepeat(Animator animation)、

、onAnimationStart(Animator animation)』 和

Animator.AnimatorPauseListener『 onAnimationPause(Animator animation)、onAnimationResume(Animator animation)』 。

Animator监听相关方法 用法释义
void addListener(Animator.AnimatorListener listener) 添加监听(在整个生命周期内through the life of an animation, such as start, repeat, and end.)
void addPauseListener(Animator.AnimatorPauseListener listener) 在暂停时监听
void removeAllListeners() 取消所有监听
void removeListener(Animator.AnimatorListener listener) 取消指定监听
void removePauseListener(Animator.AnimatorPauseListener listener) 取消指定暂停监听

三、Property Animation的计算原理

首先还是看下官方的Property Animation几个重要组件之间的关系图

比如在图2中,使用的TimeInterpolator的是AccelerateDecelerateInterpolator ,而TypeEvaluatorIntEvaluator,而ValueAnimator是属性动画的核心类封装了前两者。

组件 功能释义
ValueAnimator 包含Property Animation动画的所有核心功能,如动画时间,开始、结束属性值,相应时间属性值计算方法等
TimeInterpolator 定义动画interpolation的方式
TypeEvaluator, 一个接口, 根据开始、结束值与TimeIniterpolator计算得到的值计算出属性值。
ObjectAnimator 继承自ValueAnimator,也是一个动画执行类
AnimatorSet 用于控制一组动画的执行:线性,同时,每个动画的先后执行等。
AnimatorInflater 用户加载属性动画的xml文件

当想要start属性动画之前,系统会先建立一个ValueAnimator并为属性指定开始值和结束值,接着调用start()运行动画,在整个动画运行时期,ValueAnimator基于已经运行的时间和整个动画的持续时间的比计算出一个时间系数(范围是0——1,其中0代表0%,1代表已完成100%),然后TimeInterpolator计算出插值系数(fraction ),最后TypeAnimator通过开始时间结束时间以及插值系数计算出当时的属性值

例如:

上面例子t=10ms时ValueAnimator根据运行的时间和整个动画的持续时间的比计算出时间系数为0.25(10/40),然后TimeInterpolator计算出插值系数约为0.15,

//上例使用的是AccelerateDecelerateInterpolator,其中input为时间系数
public float getInterpolation(float input) {
    return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
}

最后TypeAnimator通过这个因子计算出在10ms时的属性值为6pix。

//插值系数fraction,开始值startValue,结束值endValue
public Float evaluate(float fraction, Number startValue, Number endValue) {
    float startFloat = startValue.floatValue();
    return startFloat + fraction * (endValue.floatValue() - startFloat);
}

四、动画系统所支持为动画定义的属性

  • Duration:动画的持续时间,默认为300ms
  • TimeInterpolation:Interpolation的计算方式,如AccelerateDecelerateInterpolator
  • TypeEvaluator:根据属性的开始、结束值与TimeInterpolation计算出的系数,计算出对应时间的属性值
  • Repeat Count and behavoir:重复次数与方式,如播放3次、5次、无限循环,可以使动画一直重复,或播放完时再反向播放
  • Animation sets:动画集合,即可以同时对一个对象应用几个动画,这些动画可以同时播放也可以对不同动画设置不同的开始偏移
  • Frame refreash delay:多少时间刷新一次,即每隔多少时间计算一次属性值(默认为10ms),最终刷新时间还受系统进程调度与硬件的影响

五、属性动画的应用

1、使用ObjectAnimator 运行属性动画

ObjectAnimator运行属性动画要求动画所作用的对象object,必须提供该对应属性的get和set方法,因为属性动画根据你传递的该属性的初始值和最终值,以动画的效果多次去调用set方法,每次传递给set方法的值都不一样,确切来说是随着时间的推移,所传递的值越来越接近最终值。简而言之,你对object的属性xxx做动画,如果想让动画生效,要同时满足两个条件。

  • ofIntofFloatofObject:ofXxx系方法用于设置动画作用的对象object、对象的实际属性、动画开始、结束、还有中间的任意个属性值。

    当对于属性值,若值传递一个的时,默认为当前对象该属性的值为开始(通过getPropName反射获取,所以这个第二个参数即属性字段必须是实际存在的),然后设置的值为终点。若传递两个,则一个为开始、一个为结束,这些ofXxx系都是返回ObjectAnimator的

static ObjectAnimator   ofFloat(Object target, String propertyName, float... values)
//其他重载形式省
  • 动画更新的过程中,会不断调用setPropName更新元素的属性,所以使用ObjectAnimator更新某个属性,object必须要提供setXxx方法,如果动画的时候没有传递初始值,那么还要提供getXxx方法,因为系统要去拿xxx属性的初始值(如果这条不满足,程序直接Crash)
支持的属性 用法
translationX,translationY View相对于原始位置的偏移量
rotation,rotationX,rotationY 旋转,rotation用于2D旋转角度,3D中用到后两个
scaleX,scaleY: 缩放比
x,y View的最终坐标,是View的left,top位置加上translationX,translationY
alpha 透明度
  • object的setXxx对属性xxx所做的改变必须能够通过某种方法反映出来,比如会带来ui的改变啥的(如果这条不满足,动画无效果但不会Crash)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <ImageView
        android:id="@+id/id_ball"
        android:layout_width="400dp"
        android:layout_height="400dp"
        android:layout_centerInParent="true"
        android:src="@mipmap/bcg"
        android:scaleType="centerCrop"
        android:onClick="runPropertyAnim"
        />
</RelativeLayout>
package com.crazymo.anim;

import android.animation.ObjectAnimator;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    public void runPropertyAnim(View v){
        ObjectAnimator
                .ofFloat(v, "rotationY", 0.0F, -360.0F)//rotationY为v的实际属性字段,如果任意传递字段值程序有可能无效果甚至crash,本例中是ImageView的实际属性
                .setDuration(5000)
                .start();
    }
}

2、使用ValueAnimator运行属性动画

ValueAnimator本身不作用于任何对象,即直接使用它没有任何动画效果。它可以对一个属性值做动画,然后通过可以监听其动画过程,在动画过程中修改我们的对象的属性值,这样也就相当于我们的对象做了动画,当然,也不要求操作的对象的属性一定要有getter和setter方法,你可以自己根据当前动画的计算值,来操作任何属性。

package com.crazymo.anim;

import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.AccelerateInterpolator;
import android.widget.ImageView;

public class MainActivity extends Activity {

    private float mScreenHeight;
    private ImageView mImage;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        mImage= (ImageView) findViewById(R.id.img_ball);
        WindowManager wm = (WindowManager)getApplicationContext()
                .getSystemService(Context.WINDOW_SERVICE);
        //int width = wm.getDefaultDisplay().getWidth();
        mScreenHeight = wm.getDefaultDisplay().getHeight();

    }
    /**
     * @param view  作用的目标对象
     */
    public void verticalRun( View view)
    {
        ValueAnimator animator = ValueAnimator.ofFloat(0, mScreenHeight
                - mImage.getHeight());
        animator.setTarget(mImage);//设置应用到的目标对象
        animator.setInterpolator(new AccelerateInterpolator());//设置加速器
        animator.setDuration(2000).start();
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mImage.setTranslationY((Float) animation.getAnimatedValue());
            }
        });
    }
}

3、AnimatorSet的应用

方法 参数及用法
AnimatorSet() 构造方法
void cancel() 取消动画集
AnimatorSet.Builder play(Animator anim) 产生Builder对象,用于设置播放动画的规则(约束)
void playSequentially(Animator… items)及重载形式 依次执行动画效果
void playTogether(Animator… items)及重载形式 同时执行动画
void setTarget(Object target) 设置应用的目标对象
void start() 启动动画集
public void runAnimSets(View view) {
        ObjectAnimator animScaleX = ObjectAnimator.ofFloat(mImage, "scaleX",
                2.0f, 0.5f);
        ObjectAnimator animScaleY = ObjectAnimator.ofFloat(mImage, "scaleY",
                2.0f, 0.5f);
        ObjectAnimator animAlpha=ObjectAnimator.ofFloat(mImage,"alpha",1.0f,0.0f);
        AnimatorSet animSet = new AnimatorSet();
        animSet.setDuration(4000);
        animSet.setInterpolator(new LinearInterpolator());
        //三个动画同时执行
        animSet.playTogether(animScaleX, animScaleY,animAlpha);
        animSet.start();
    }

动画开始时先扩大两倍然后再缩小同时透明度减小为0

六、xml文件创建属性动画

1、首先在res下建立animator文件夹,然后建立对应的xml文件,根节点为set嵌套objectAnimator(其中orderring属性值:同时执行together,依次执行sequentially)或者直接为objectAnimator

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000"
    android:propertyName="scaleX"
    android:valueFrom="1.0"
    android:valueTo="0.5"
    android:valueType="floatType" >
</objectAnimator>
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="together" >
    <objectAnimator
        android:duration="3000"
        android:propertyName="scaleX"
        android:valueFrom="1"
        android:valueTo="0.5" >
    </objectAnimator>
    <objectAnimator
        android:duration="0000"
        android:propertyName="scaleY"
        android:valueFrom="1"
        android:valueTo="0.5" >
    </objectAnimator>
    <objectAnimator
        android:duration="3000"
        android:propertyName="alpha"
        android:valueFrom="1.0"
        android:valueTo="0">
    </objectAnimator>
</set>

2、然后使用AnimatorInflater加载动画的资源文件

// 加载动画
Animator anim = AnimatorInflater.loadAnimator(this, R.animator.animator_scalealpha);

3、给目标View设置旋转、缩放、反转等的中心点或者轴,(默认中心缩放,和中间对称线为反转线),然后手动触发View重绘

mImage.setPivotX(0);
mImage.setPivotY(0);
//触发重绘
mImage.invalidate();
//mImage.postInvalidate();

4、给Animator设置target并start动画,Over。

anim.setTarget(mImage);
anim.start();

完整的方法

public void runXmlAnimSet(View v){
       Animator anim = AnimatorInflater.loadAnimator(this, R.animator.animator_scalealpha);
       mImage.setPivotX(0);
       mImage.setPivotY(0);
       //显示的调用invalidate
       mImage.invalidate();
       mImage.postInvalidate();
       anim.setTarget(mImage);
       anim.start();
   }

七、Property Animation与View Animation的区别

Property Animation它更改的是对象的实际属性,本质就是系统根据特定的算法不断地动态改变对象的实际属性从而形成一种动画效果,而在View Animation(Tween Animation)中,其改变的是View的绘制效果,真正的View的属性保持不变,比如说无论你在对话中如何缩放Button的大小,Button的有效点击区域还是没有应用动画时的区域,其位置与大小都不变。而在Property Animation中,改变的是对象的实际属性,如Button的缩放,Button的位置与大小属性值都改变了。而且Property Animation不止可以应用于View,还可以应用于任何对象。

时间: 2024-11-08 15:47:12

Android进阶——属性动画Property Animation详解(一)的相关文章

Android 动画详解之属性动画(Property Animation)(下)

Hello,大家好,最近好长时间没有写博客了,因为我决定辞职了. 废话不多说,我们还是来看属性动画在上一篇Android 动画详解之属性动画(Property Animation)中我们简单的介绍了一下属性动画的用法,其实属性动画还有更多有趣的用法. 1,在xml中使用 在eclipse中我们右键新建xml可以选择新建属性动画,如图 我们选择objectAnimator,然后我们就会看到熟悉的一幕 然后我们用智能提示就可以看到更熟悉的 没错,这下我们应该知道怎么用xml布局来写属性动画了吧 <s

Android属性动画Property Animation系列一之ObjectAnimator

转载请注明出处 http://blog.csdn.net/feiduclear_up/article/details/45915377 前面一篇博客解读了Android属性动画Property Animation系列一之ValueAnimator的相关知识点以及怎么使用.这篇博客继续解读Android 属性动画 ObjectAnimator 类的使用. ObjectAnimator 相比ValueAnimator类,ObjectAnimator更加实用,因为它真正可以作用在一个对象上.不过Obj

Android属性动画Property Animation系列三之LayoutTransition(布局容器动画)

在上一篇中我们学习了属性动画的ObjectAnimator使用,不了解的可以看看 Android属性动画Property Animation系列一之ObjectAnimator.这一篇我们来学点新的东西.做项目的时候应该碰到这种问题:根据不同条件显示或者隐藏一个控件或者布局,我们能想到的第一个方法就是 调用View.setVisibility()方法.虽然实现了显示隐藏效果,但是总感觉这样的显示隐藏过程很僵硬,让人不是很舒服,那么有没有办法能让这种显示隐藏有个过渡的动画效果呢?答案是肯定的,不言

Android属性动画Property Animation系列一之ValueAnimator

Android动画分类 市面上的很多APP都用到动画效果,动画效果用的好可以提升用户的体验度.那么Android系统都有哪些机制的动画呢? 1.逐帧动画(frame-by-frame animation).逐帧动画的工作原理很简单,其实就是将一个完整的动画拆分成一张张单独的图片,然后再将它们连贯起来进行播放,类似于动画片的工作原理. 2.补间动画(tweened animation)则是可以对View进行一系列的动画操作,包括淡入淡出.缩放.平移.旋转四种. 3.属性动画Property Ani

转 Android Activity之间动画完整版详解

标签:Android Activity动画详解 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://mzh3344258.blog.51cto.com/1823534/807337 大家可能遇到过跟小马一样的问题,就是在项目中不给Activity添加动画感觉好烂,特此,小马找个时间学习下Activity跳转时添加动画,网上资料一堆,但有些讲的是错的,而且只有文字没有效果,不如自己来,顺带试下什么效果,这个工程里面小马收集了一些常用

属性动画-Property Animation之ViewPropertyAnimator 你应该知道的一切

转载请注明出处(万分感谢!): http://blog.csdn.net/javazejian/article/details/52381558 出自[zejian的博客] 关联文章: 走进绚烂多彩的属性动画-Property Animation(上篇) 走进绚烂多彩的属性动画-Property Animation之Interpolator和TypeEvaluator(下篇) ??原本打算这篇作为属性动画的完结篇,但目前情况来看,估计无法完结,前两天研究了一下ViewPropertyAnimat

Android 动画详解之属性动画(Property Animation)

转载请注明http://blog.csdn.net/u014163726/article/details/41210951 前文也提到过Android 3.0以后引入了属性动画,属性动画可以轻而易举的办到许多View动画做不到的事,今天我们就来学习一下属性动画. 前文提到过View动画只是改变了View的绘制效果,而属性动画则是真正的改变一个属性,效果如下图. 对比Android 动画详解之View动画我们可以看到明显的区别,那么属性动画究竟是怎么用的呢,莫慌,接下来代码奉上. 1,Object

Android学习之 属性动画&lt;Property Animation&gt;

property 动画系统是相当健壮的框架,它几乎可以动画显示任何对象. 你可以定义一个动画来定时改变任何对象的属性值,不论该对象是否在屏幕上显示. property 动画将以一定的时间间隔修改属性值(对象中的字段值). 要实现动画显示,你须指定对象的相应属性(比如对象的屏幕位置),以及动画时长.动画时间间隔. property 动画系统能让你设定以下动画要素: 1.持续时间:指定动画的持续显示时间.默认的时长是300毫秒. 2.插值因子:指定属性值的变化方式,表示为关于动画已显示时间的函数.

Android动画--属性动画Property Animation

简介 属性动画包含: ObjectAnimator 动画的执行类 ValueAnimator 动画的执行类 AnimatorSet 用于控制一组动画的执行:线性,一起,每个动画的先后执行等. AnimatorInflater 用户加载属性动画的xml文件 ObjectAnimator 单一属性动画 缩放X轴:ScaleX ObjectAnimator().ofFloat(imageView,"ScaleY",1.0f,0.0f).setDuration(3000).start(); 缩