Android 属性动画 详解

认识属性动画

传统动画Animation平移方法的实现

TranslateAnimation animation = new TranslateAnimation(x轴初始位置,x轴终止位置,y轴初始位置,y轴终止位置);

animation.setDuration(1000);//设置持续时间,ms单位

animation.setFillAfter(true);//设置动画结束后状态,true为保持最终状态

imageView.startAnimation(animation);//为控件添加要执行的动画

传统动画的局限性,只是重绘了动画,改变了显示位置,但是真正的响应位置没有发生任何改变,并不适合做具有交互的动画效果

传统动画框架的局限性:只是重绘了View,但是View原来相应事件的位置并没有改变,这样就会使得View在动画结束后,点击View没有相应,而点击View原来的位置才有响应,这就是一个很诡异的事情。

属性动画Animator与传统动画Animation

package com.example.animationtest;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

}
public void click(View view){
Toast.makeText(this, "click", Toast.LENGTH_SHORT).show();
}
public void move(View view){
TranslateAnimation animation = new TranslateAnimation(0, 200, 0, 0);
animation.setDuration(2000);
animation.setFillAfter(true);
ImageView imageView = (ImageView) findViewById(R.id.imageView1);
imageView.startAnimation(animation);
}

}

ObjectAnimator

一、ObjectAnimator属性动画

1.ObjectAnimator.ofFloat(view,”“,float,float).setDuration(1000).start();

第二个参数:

translationX、translationY偏移量

rotation旋转

X、Y偏移至

2.同时作用三个属性动画

PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat(“rotation”,0,360f);

ObjectAnimator.ofPropertyValuesHolder(view,p1,p2,p3).setDuration(1000).start();

二、AnimatorSet

1.同时作用三个属性动画

ObjectAnimator animator1 = ObjectAnimator.ofFloat(view,”rotation”,0,360F);

AnimatorSet set = new AnimatorSet();

set.playTogether(animator1,animator2,animator3);

set.start();

2.顺次播放动画

set.playSequentially(animator1,animator2,animator3);

3.组合动画

set.play(animator2).with(animator3);

set.play(animator1).after(animator2);

动画二和动画三同时播放,结束后播放动画一

Animator同样支持AnimatorSet,增加动画组合的多样性

playSequentially:按顺序进行动画的播放

playTogether:一起执行所选的动画效果

还可以进行属性集合的详细控制

set.play(动画2).with(动画3);

set.play(动画1).after(动画2);

属性动画平移的实现方法

ObjectAnimatior.ofFloat(imageView,”translationX”,0F,200f).setDuration(1000).start();

//ofFloat方法(要操作的对象,”要操作的元素”,变化范围,变化范围).设置持续时间.开始执行

要操作的元素只要包含get和set方法都可以使用属性动画,例如

translationX/translationY:X/Y轴的偏移量

X/Y:X/Y的最终量

rotation:旋转,从0度开始

ObjectAnimatior.ofFloat()方法实现的动画是同时进行的,同时操作多个属性的动画可以使用ofPropertyValuesHolder方法

PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat(“rotation”,0,360F);

PropertyValuesHolder p2 = PropertyValuesHolder.ofFloat(“translationX”,0,360F);

PropertyValuesHolder p3 = PropertyValuesHolder.ofFloat(“translationY”,0,360F);

ObjectAnimatior.ofPropertyValuesHolder(imageView,p1,p2,p3).setDuration(1000).start();

1.ObjectAnimation.ofFloat(动作对象,String类型动作属性,float类型动作数值);

动作属性:”translationX”,”X”,”rotation”

2.多个属性动画可以同时进行,为了优化动作属性可以用以下方法:

PropertyValuesHolder p1=PropertyValuesHolder.ofFloat(“rotation”,0,360f);

ObjectAnimator.ofPropertyValuesHolder(对象, p1,p2,p3).setDuration(1000).start();

3.用set方法:

ObjectAnimator animator1=ObjectAnimator.ofFloat(对象,”属性名”,Values);

AnimatorSet set=new AnimatorSet();

set.playTogether(animator1,animator2,animator3);同时运行

set.playSequentially(animator1,animator2,animator3);连续运行

set.play(animator2).with(animator3);同时进行

set.play(animator1).after(animator3);animator1在animator3后运行

Animation平移动画 耗CPU Google提供了很多例子

TranslateAnimation animation=new TranslateAnimation(x0,x1,y0,y1)

animation.setDuration(1000)设置时间

animation.setFillAfter(true)保留平移后位置

imageview.setAnimation(animation);

属性动画:监听事件也跟着一起移动了

ObjectAnimator.ofFloat(imageview,”translationX”,0F,200F).setDuration(1000).start()

只要是有get和set的属性都可以添加属性动画

—-属性动画是异步执行的,多写几行一起动 亦可传递PropertyValueHolder来保存属性的变化,然后一起传进去ObjectAnimation.ofPropertyValueHolder(imageview,p1,p2,p3)

translationX改为X就是绝对位置

—————rotation就是旋转

使用PropertyValuesHolder实现组合动画效果。
PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("rotation",0,360F);
PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("translationX",0,360F);
PropertyValuesHolder p1 = PropertyValuesHolder.ofFloat("translationY",0,360F);
ObjectAnimatior.ofPropertyValuesHolder(imageView,p1,p2,p3).setDuration(1000).start();
·使用AnimatorSet来完成 {
AnimatorSet set = new AnimatorSet();
ObjectAnimator animator1 = ObjectAnimator.offloat(imageView, "rotation", 0f, 200f);
ObjectAnimator animator2 = ObjectAnimator.offloat(imageView, "translationX", 0f, 200f);
ObjectAnimator animator3 = ObjectAnimator.offloat(imageView, "translationY", 0f, 200f);
set.playTogether(animator1,animator2,animator3); // 动画一起播放
// set.playSequentially(animator1,animator2,animator3); // 顺序播放动画
// 控制动画之间的播放顺序
// set.play(animator2).with(animator3); // 先X和Y一起平移
// set.play(animator1).after(animator3); // 平移完成之后旋转
set.setDuration(1000);
set.start();
}

动画监听事件

分享一下个人实现的环形菜单效果,按钮是发散成圆排布的。

float y = (float) (r * Math.sin((Math.PI / 2) / (res.length - 2) * (i - 1)));

float x = (float) (r * Math.cos((Math.PI / 2) / (res.length - 2) * (i - 1)));

ObjectAnimator animator = ObjectAnimator.ofFloat(viewList.get(i), “translationY”,

0f, -y);

ObjectAnimator animator2 = ObjectAnimator.ofFloat(viewList.get(i), “translationX”,

0f, x);

x,y是通过数学知识计算出来的,改变x,y 的正负值,菜单弹出的方向也可以改变,其他的代码和老师的相同。

动画是速度interpolator,他可以定义动画的速度变化,从而实现更加复杂的动画效果。设置interpolator的方法:

ObjectAnimator的setInterpolator()方法,参数可以传递各种各样的interpolator,比如:

objectAnimator.setInterpolator(new BounceInterpolator());

animator.addListener(new AnimatorListenerAdapter); //只要重写一个事件

animator.setStartDelay(x);//依次弹出x为间隔毫秒

setInterpolator(new XXX);//设置动画的速度变换

alpha 透明度

rotation z轴旋转

rotationX x轴旋转

rotationY y轴旋转

translationX x水平偏移

translationY y水平偏移

ScaleX x轴缩放

ScaleY y轴缩放

AccelerateDecelerateInterpolator 在动画开始与结束的地方速率改变比较慢,在中间的时候加速

AccelerateInterpolator 在动画开始的地方速率改变比较慢,然后开始加速

AnticipateInterpolator 开始的时候向后然后向前甩

AnticipateOvershootInterpolator 开始的时候向后然后向前甩一定值后返回最后的值

BounceInterpolator 动画结束的时候弹起

CycleInterpolator 动画循环播放特定的次数,速率改变沿着正弦曲线

DecelerateInterpolator 在动画开始的地方快然后慢

LinearInterpolator 以常量速率改变

OvershootInterpolator 向前甩一定值后再回到原来位置

alpha 透明度

rotation z轴旋转

rotationX x轴旋转

rotationY y轴旋转

translationX x水平偏移

translationY y水平偏移

ScaleX x轴缩放

ScaleY y轴缩放

Tips:
1.ObjectAnimator.ofFloat(view,"alpha",0F,1F);

一、给Animator添加监听
1.animator.addListener(new Animator.AnimatorListener(){...});
2.animator.addListener(new AnimatorListenerAdapter(){...});不需重写所有事件方法

二、例子
1.animator.setStartDelay(300);动画延时0.3s
2.animator.setInterpolator(new BounceInterpolator());差值器(弹性)
ObjectAnimator animator = ObjectAnimator.ofFloat(view,"alpha",0,1f).setDuration(1000);
animator.addListener(new Animator.AnimatorListener() {
public void onAnimationStart(Animator animation) {
}
public void onAnimationEnd(Animator animation) {
}
public void onAnimationCancel(Animator animation) {
}
public void onAnimationRepeat(Animator animation) {
}
});
//选择监听事件
animator.addListener(new AnimatorListenerAdapter(){

});

//差值器(均速度,加速度,抛物线)内置九种差值器
animator,setInterpolator(new BounceInterpolator());

public class ListenForAnEvent extends Activity implements OnClickListener {

    private int[] ids = {R.id.a, R.id.b, R.id.c, R.id.d, R.id.e, R.id.f, R.id.g, R.id.h };
    private List<ImageView> imageViewList = new ArrayList<ImageView>();
    private boolean flag = false;
    private int r = 250;

    /*
     * (非 Javadoc) Description:
     * @see android.app.Activity#onCreate(android.os.Bundle)
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_listen_event);
        for (int i = 0; i < ids.length; i++) {
            ImageView imageView = (ImageView) findViewById(ids[i]);
            imageViewList.add(imageView);
            imageView.setOnClickListener(this);
        }
    }

    /*
     * (非 Javadoc) Description:
     * @see android.view.View.OnClickListener#onClick(android.view.View)
     */
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.a:
            if (!flag) {
                startAnimator();
            } else {
                closeAnimator();
            }
            break;

        default:
            Toast.makeText(ListenForAnEvent.this, "Image=" + v, Toast.LENGTH_SHORT).show();
            break;
        }
    }

    /**
     * @Description (关闭动画)
     */
    private void closeAnimator() {
        for (int i = 1; i < ids.length; i++) {
            float y = (float) (r * Math.sin((Math.PI / 2) / (ids.length / 2) * (i - 1)));
            float x = (float) (r * Math.cos((Math.PI / 2) / (ids.length / 2) * (i - 1)));
            ObjectAnimator animatorX = ObjectAnimator.ofFloat(imageViewList.get(i), "translationX", x, 0);
            ObjectAnimator animatorY = ObjectAnimator.ofFloat(imageViewList.get(i), "translationY", y, 0);
            AnimatorSet animator = new AnimatorSet();
            animator.playTogether(animatorX, animatorY);
            // ObjectAnimator animator = ObjectAnimator.ofFloat(imageViewList.get(i), "translationY", i * 100F, 0);
            animator.setDuration(1000);
            animator.setInterpolator(new BounceInterpolator());
            animator.setStartDelay(i * 1000);
            animator.start();
            flag = false;
        }

    }

    /**
     * @Description (开启动画)
     */
    private void startAnimator() {
        for (int i = 1; i < ids.length; i++) {
            float y = (float) (r * Math.sin((Math.PI / 2) / (ids.length / 2) * (i - 1)));
            float x = (float) (r * Math.cos((Math.PI / 2) / (ids.length / 2) * (i - 1)));
            Log.d("jia", "y=" + y);
            ObjectAnimator animatorX = ObjectAnimator.ofFloat(imageViewList.get(i), "translationX", 0, x);
            ObjectAnimator animatorY = ObjectAnimator.ofFloat(imageViewList.get(i), "translationY", 0, y);
            AnimatorSet animatorSet = new AnimatorSet();
            animatorSet.playTogether(animatorX, animatorY);

            // ObjectAnimator animatorSet = ObjectAnimator.ofFloat(imageViewList.get(i), "translationY", 0, i * 100F);
            animatorSet.setDuration(2000);
            animatorSet.setInterpolator(new OvershootInterpolator());
            animatorSet.setStartDelay(i * 1000);
            animatorSet.start();
            flag = true;
        }
    }
}

ValueAnimator

ObjectAnimator常用属性:

translationX、translationY ;rotation、rotationX、rotationY ;scaleX、scaleY ; X、Y ; alpha

常用方法、类:

ValueAnimator、ObjectAnimator、AnimatorUpdateListener、AnimatorListenerAdapter、PropertyValuesHolder、AnimatorSet、TypeEvalueators、Interpolators

2.ofObject()自定义

ValueAnimator animator = ValueAnimator.ofObject(new TypeEvaluator(){

//fraction时间因子,0~1

public Object evaluate(float fraction, PointF startValue, PointF endValue){

return null;

}

});

三、总结

1.ObjectAnimator常用属性:

translationX、translationY ;rotation、rotationX、rotationY ;scaleX、scaleY ; X、Y ; alpha

2.常用方法、类

ValueAnimator、ObjectAnimator、AnimatorUpdateListener、AnimatorListenerAdapter、PropertyValuesHolder、AnimatorSet、TypeEvalueators、Interpolators

在属性动画框架中最常用的方法和类:

ValueAnimator

ObjectAnimator

AnimatorUpdateListener

AnimatorListenerAdapter

PropertyValuesHolder

AnimatorSet

TypeEvaluators

Interpolators

一、ValueAnimator

1.ValueAnimator本身并不会作用于任何一个属性,也不会提供任何一个动画,它是一个数值发生器

2.计算属性动画中每一步的具体动画效果

3.如何产生值:

ValueAnimator会根据动画已进行的时间与其持续的总时间的比值产生一个0~1的时间因子,有了这样一个时间因子,经过相应的变换,就可以根据startValue()和endValue()来生产中间的相应值。同时,通过插值器的使用,可以进一步地控制每一个时间因子产生值的变化速率。

4.ObjectAnimator继承自ValueAnimator

二、ValueAnimator的使用

1.ofInt()

ValueAnimator animator = ValueAnimator.ofInt(0,100);

animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener{

public void onAnimationUpdate(ValueAnimator animation){

Integer value = (Integer)animation.getAnimatedValue();

}

});

下面的例子是利用ValueAnimator实现一个Button上数字的改变。ValueAnimator是一个timing engine,他负责进行动画时候变化的中间值的计算,比如这个例子,我们就是想看在5000毫秒内,如果一个值从0变化到100,并且进行匀速变化的话是什么情况(我们没有为ValueAnimator设置Interpolator,所以默认的就是匀速变化)。通过addUpdateListener()方法我们可以监听到ValueAnimator在计算和改变值的时候每一帧数据,所以在这个监听器的回调方法中我们就可以通过getAnimatedValue()来获取每一帧的值,从而将它设置到UI上,实现我们想要的效果。所以如果我们不想要动画效果,只关心动画中各个值的变化,我们想获取这些变化的值在动画中的中间值和这些值的变化效果,我们就可以考虑使用ValueAnimator(这个类的名字也取的很贴切)。

ValueAnimator数值发生器

产生数值

ofInt(1,100)

ValueAnimator的addUpdateListener()监听获取每一步产生的数值

—————-在匿名内部类中通过getAnimatedValue()方法获得数值

自定义数值发生器:

ValueAnimator.ofObject(new TypeEvaluator<可指定泛型>(){实现evaluate(0-1的时间因子,开始,结束值)方法})

一、ValueAnimator

1.ValueAnimator本身并不会作用于任何一个属性,也不会提供任何一个动画,它是一个数值发生器

2.计算属性动画中每一步的具体动画效果

3.如何产生值:

ValueAnimator会根据动画已进行的时间与其持续的总时间的比值产生一个0~1的时间因子,有了这样一个时间因子,经过相应的变换,就可以根据startValue()和endValue()来生产中间的相应值。同时,通过插值器的使用,可以进一步地控制每一个时间因子产生值的变化速率。

4.ObjectAnimator继承自ValueAnimator

二、ValueAnimator的使用

1.ofInt()

ValueAnimator animator = ValueAnimator.ofInt(0,100);

animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener{

public void onAnimationUpdate(ValueAnimator animation){

Integer value = (Integer)animation.getAnimatedValue();

}

});

时间: 2024-08-01 05:22:24

Android 属性动画 详解的相关文章

Android Animation动画详解(二): 组合动画特效

前言 上一篇博客Android Animation动画详解(一): 补间动画 我已经为大家介绍了Android补间动画的四种形式,相信读过该博客的兄弟们一起都了解了.如果你还不了解,那点链接过去研读一番,然后再过来跟着我一起学习如何把简单的动画效果组合在一起,做出比较酷炫的动画特效吧. 一. 动画的续播 如题,大家想想,如果一个页面上包含了许多动画,这些动画要求按顺序播放,即一个动画播放完成后,继续播放另一个动画,使得这些动画具有连贯性.那该如何实现呢? 有开发经验或者是逻辑思维的人肯定会想,对

属性动画详解一(Property Animation)

效果图: Android动画有两类: 1.View Animation(Frame Animation,Tween Animation) 2.Property Animation 其中,上述效果是用第二类属性动画做的. 什么是属性动画? 通俗的说,属性动画就是在一定的时间内,按照一定的规律来改变对象的属性(该属性对于该对象应该是从形态(大小,位置等)上可以感受到的),从而是对象展现出动画的效果. 作用:可以定义动画来改变对象的属性( You can define an animation to

Android自定义view教程03---Android 属性动画 详解

1 package com.example.donghuatest; 2 3 import android.animation.ObjectAnimator; 4 import android.animation.PropertyValuesHolder; 5 import android.animation.ValueAnimator; 6 import android.animation.ValueAnimator.AnimatorUpdateListener; 7 import andro

Android:属性动画详解

(一)简介 属性动画是Android 3.0中提供了新功能,便于对任意元素进行"平滑的过渡".众所周知,Android 之前提供的补间动画如AlphaAnimation.TranslateAnimation等都只能应用在View上,并且几乎没有任何可扩展的地方.并且,使用原来的动画无法实现颜色渐变效果,算是一个遗憾. 属性动画彻底打破了这种设计方式,不再将这些动画强制的放在View上,而是仅仅产生一系列的值,由开发人员自行使用这些值.例如,属性动画可产生1-0平滑过渡的值,把这些值应用

Android中PropertyAnimation属性动画详解(一)

在之前的文章中已经讲了帧动画frame-by-frame animation和补间动画tweened animation,其实这两种动画原理好简单,都是按照预先固定的动画模式来播放的,帧动画将一张张单独的图片,然后把它们连贯起来进行播放,就形成了动画效果,补间动画则是可以对View对象进行一系列的动画操作,包括淡入淡出.缩放.平移.旋转四种,不过这几种都是完全按照我们预先设置好的效果来执行,不能动态的改变,所以,在Android3.0以后就引入了属性动画PropertyAnimation来满足一

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

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

android之属性动画和布局动画详解

1.属性动画是什么不废话,不懂的可以百度一下参考郭霖大神的动画详解篇:这里仅仅提供一个demo说说用法,抛砖引玉,代码的注释写的已经很详细,不再多说废话,一下提供的是一个基础的demo,讲解的是objectAnimator的基础用法,如平移.旋转.缩放.渐变以及动画的集合:至于objectAnimator(必须的有set get方法)和valueAnimator的详细区别也可参考郭霖大神的动画详解篇 2.除此基本用法,还有估值器和插值器 (1)插值器:动画速率的变换,有点类似物理的加速度,就是该

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

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

android动画详解三 动画API概述

· 属性动画与view动画的不同之处 view动画系统提供了仅动画View 对象的能力,所以如果你想动画非View 对象,你就要自己实现代码. view动画系统实际上还被强制仅能对 View 的少数属性进行动画,比如缩放和旋转,而不能对背景色进行. view动画的另一个坏处是它仅修改View的绘制位置,而不是View的实际位置.例如,如果你动画一个移动穿越屏幕,button的绘制位置是正确的,但实际你可以点击它的位置却没有变,所以你必须去实现你自己的逻辑来处理它. 使用属性动画系统时,这个限制被