Android动画全解

在Android开发中经常会碰到动画,看到别的应用有很酷炫的应用时,总是想怎么去实现,但是每次都是发现感觉是知道怎么做的,实际做起来还是无从下手的感觉,究其原因还是

Android动画方面的知识不全面,这几天利用空闲时间研究了下Android动画知识,当作学习日记,大家也好有所借鉴。

Android主要分三类动画:Tween Animation、Frame Animation、Property Animation。

其中Tween Animation、Frame Animation是在Android是在Android3.0之前就有的动画技术,后来由于动画需求越来越高,Tween Animation、Frame Animation已经满足不了应用对于动画效果的需求了,于是在Android3.0之后,谷歌又增加了新的动画Property Animation。下面对这三种动画逐个介绍。

一、Tween Animation

中文亦叫补间动画,它是通过平移、旋转、缩放以及修改透明度来达到动画效果的,原理是给出两个关键帧,通过一些算法将给定属性值在给定时间内在两个关键帧间渐变。这里我们只关心动画的使用,不关注它的代码实现。Tween Animation基于Animation类扩展,有以下几个Tween Animation类:TranslateAnimation(平移)、AlphaAnimation(透明度)、ScaleAnimation(缩 放)、RotateAnimation(旋转)。

TranslateAnimation使用方法如下:

private TranslateAnimation mTranslateAnimation;
//这四个参数含义分别是当前View x起点坐标、x终点坐标、y起点坐标、y终点坐标
mTranslateAnimation = new TranslateAnimation(0, 200, 0, 0);
//动画持续时间
mTranslateAnimation.setDuration(2000);
//重复次数
mTranslateAnimation.setRepeatCount(1);
//动画执行模式
mTranslateAnimation.setRepeatMode(Animation.REVERSE);

以上代码含义为从view的起点开始,保持y轴不变,沿着x平移200个像素,平移时间为2秒,重复执行一次,第二次执行方式与第一次执行方式完全相反,如下图:

以上是java代码实现的方式,亦可以使用xml实现,如下:

/res/anim/translate.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:fromXDelta="0"
        android:toXDelta="200"
        android:fromYDelta="0"
        android:toYDelta="0"
        android:duration="2000"
        android:repeatCount="1"
        android:repeatMode="reverse"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"/>
</set>

fromXDelta:View x轴起点

toXDelta:View x轴终点

fromYDelta:View y轴起点

toYDelta:View y轴终点

duration:动画持续时间

repeatCount:动画执行次数

repeatMode:动画执行模式

interpolator:插值器,可以理解为View动画值的改变规律

java中调用:

private Animation mTranslateAnimation;
mTranslateAnimation = AnimationUtils.loadAnimation(this, R.anim.translate);
mTranslateIv.startAnimation(mTranslateAnimation);

使用Java或者xml实现动画并无什么不同,采用哪种完全取决于自己的编程习惯,但如果单纯从扩展性来说,显然xml方式更占优。

AlphaAnimation使用方法如下:

private AlphaAnimation mAlphaAnimation;
//不透明度从100%到0
mAlphaAnimation = new AlphaAnimation(1, 0);
mAlphaAnimation.setDuration(2000);
mAlphaAnimation.setRepeatCount(1);
mAlphaAnimation.setRepeatMode(Animation.REVERSE);

以上代码含义是在2秒内将View的不透名度从1变为0,总共执行2次,第一次和第二次执行动画过程相反,效果如下图:

xml实现方法可参照TranslateAnimation

ScaleAnimation使用方法如下:

mScaleAnimation = new ScaleAnimation(1, 2, 1, 2);
mScaleAnimation.setDuration(2000);
mScaleAnimation.setRepeatCount(1);
mScaleAnimation.setRepeatMode(Animation.REVERSE);

上面ScaleAnimation构造函数中四个参数分别是:

fromX:起始x方向大小

toX:最终x方向大小

fromY:起始y坐标

toY:最终y坐标

上面代码含义为将View在2秒内横竖方向增大一倍,第二次是在原来的基础上缩小一倍,效果图如下:

xml实现方法同参照TranslateAnimation

RotateAnimation使用方法如下:

mRotateAnimation = new RotateAnimation(0, 360);
mRotateAnimation.setDuration(2000);
mRotateAnimation.setRepeatCount(1);
mRotateAnimation.setRepeatMode(Animation.REVERSE);

上面代码含义为在2秒内将View旋转360度,再旋转回来,效果如下:

二、Frame Animation

看过电影的人也许知道,电影是由一张一张图片组成的,只不过图片切换速度快,在人视觉中看到的是连续效果。Frame Animation亦同样基于此原理实现,事先准备几张图片,按特定的顺序排好,然后使用特定的动画类将其播放,基于这种动画实现方式,Frame Anmation亦有一个中文名:逐帧动画。

实现这种动画需要使用到AnimationDrawable类,它继承于Drawable,使用方式如下:

private AnimationDrawable mAnimationDrawable;
mAnimationDrawable = new AnimationDrawable();
//增加图片,并设定图片播放时间
mAnimationDrawable.addFrame(getResources().getDrawable(R.drawable.australia), 500);
mAnimationDrawable.addFrame(getResources().getDrawable(R.drawable.austria), 500);
mAnimationDrawable.addFrame(getResources().getDrawable(R.drawable.china), 500);
mAnimationDrawable.start();

上面代码是将三张图片按照指定的顺序,指定的时间播放,以达到动画效果,如下图:

同样亦可以使用xml方式实现,代码如下:

/anim/frame.xml

<?xml version="1.0" encoding="utf-8"?>
<animation-list
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">

    <item android:drawable="@drawable/australia" android:duration="500"/>
    <item android:drawable="@drawable/austria" android:duration="500"/>
    <item android:drawable="@drawable/china" android:duration="500"/>
</animation-list>

xml中调用:

<ImageView
        android:id="@+id/frame_iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@anim/frame"/>

java中调用:

private ImageView mFrameIv;
private AnimationDrawable mAnimationDrawable;
mFrameIv = (ImageView) findViewById(R.id.frame_iv);
mAnimationDrawable = (AnimationDrawable) mFrameIv.getBackground();
mAnimationDrawable.start();

关于Frame Tween的知识比较简单,熟悉AnimationDrawable便行,下面介绍本章最重要的Property Animation。

三、Property Animation

中文亦叫属性动画,如其名字一样,可以改变对象的属性,注意是对象,不是View,而且是任意对象,只要对象符合一定条件即可,上述中的Tween Animation仅仅只能操作View,对于View之外的对象则无能为力,并且其未改变View的属性,仅仅是通过父类View对其重绘达到动画效果;而Frame Animation动画功能则过于简单。随着我们Android应用的发展,能发现Tween Animation、Frame Animation有时候并不能达到理想的效果,谷歌亦意识到了这点,故而在Android3.0之后增加了强大的属性动画。

Property Animation有两个类可供使用:ValueAnimator、ObjectAnimator。这两个类均直接或间接继承于Animator

ObjectAnimator使用方式如下:

private ObjectAnimator mObjectAnimator;
//设置不透明度从1到0变化
mObjectAnimator = ObjectAnimator
                .ofFloat(mObjectAnimatorIv, "alpha", 1, 0)
                .setDuration(1000);
//设置插值器,先加速后减速
mObjectAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
//动画重复执行一次
mObjectAnimator.setRepeatCount(1);
//设置执行模式
mObjectAnimator.setRepeatMode(ValueAnimator.REVERSE);
mObjectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        //获取当前的动画值
        float cVal = (Float) animation.getAnimatedValue();
        //根据动画值缩放当前View
        mObjectAnimatorIv.setScaleX(cVal);
        mObjectAnimatorIv.setScaleY(cVal);
    }
});

上面代码意思是将当前View不透明度从1按照一定规律变为0,第一句代码中的ofFloat(mObjectAnimatorIv, "alpha", 1, 0)中的alpha代表不透明度,有人可能会说我可以写其他的吗?当然可以,比如写成ofFloat(mObjectAnimatorIv, "tmg", 1, 0),但你会发现动画执行后不会有效果,因为写这个字符串的前提是当前View或者当前View的父类中实现了这个字符串的get、set方法,即getAlpha、setAlpha,当动画执行时,动画类会通过调用setAlpha来改变View的alpha属性,达到想要的动画效果。那这个alpha是怎么从1便到0的呢?Property Animation中有一个TypeEvaluator,这个属性的含义是根据属性的开始、结束值与TimeInterpolation计算出的因子计算出当前时间的属性值,上例中的alpha便是这样从1变到0的,但是上面并没设置TypeEvaluator啊?其原因是Property Animation

会配置一个默认的TypeEvaluator,如果一定要显性设置,有几个写好的TypeEvaluator供选择:

IntEvaluator:属性值的类型为int

FloatEvaluator:属性值的类型为float

ArgbEvaluator:属性的值类型为十六进制颜色值

如果上述没有你需要的TypeEvaluator,你亦可以选择继承TypeEvaluator自定义一个类似的TypeEvaluator

从上面代码中我们还可以看到:

float cVal = (Float) animation.getAnimatedValue();
mObjectAnimatorIv.setScaleX(cVal);
mObjectAnimatorIv.setScaleY(cVal);

其中animation.getAnimatedValue();是计算View当前属性值,当然根据前面的设置,这个属性值实在1到0之间变化,下面的两行代码是通过每个时刻不同的属性值对View进行缩放,达到在改变透明度的同时,

又改变View大小的效果,效果图如下:

同样的,Property Animation也可以通过xml实现,类似上面两种,不再介绍,读者可从之后分享的源码中看到

ValueAnimator的使用方式和ObjectAnimator很相似,唯一的区别是ValueAnimator不能直接设置属性,即类似

mObjectAnimator = ObjectAnimator
                .ofFloat(mObjectAnimatorIv, "alpha", 1, 0)
                .setDuration(1000);

它只能这样:

mValueAnimator = ValueAnimator.ofFloat(1, 0);
mValueAnimator.setTarget(mValueAnimatorIv);

动画效果可在监听事件中实现,如:

mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        float animatedValue = (float) animation.getAnimatedValue();
        mValueAnimatorIv.setAlpha(animatedValue);
        mValueAnimatorIv.setScaleX(animatedValue);
        mValueAnimatorIv.setScaleY(animatedValue);
    }
});

谈谈Keyframe,keyframe是一个时间/值对,通过它可以定义一个在特定时间的特定状态,

即关键帧,而且在两个keyframe之间可以定义不同的Interpolator,就好像多个动画的拼接,第一个动画的结束点是第二个动画的开始。keyframe是抽象类,要通过ofInt(),ofFloat()等获得适当的keyframe,然后通过PropertyValuesHolder.ofKeyframe

获得PropertyValuesHolder对象,如下例子:

Keyframe kf0 = Keyframe.ofInt(0, 400);
Keyframe kf1 = Keyframe.ofInt(0.25f, 200);
Keyframe kf2 = Keyframe.ofInt(0.5f, 400);
Keyframe kf3 = Keyframe.ofInt(0.75f, 100);
Keyframe kf4 = Keyframe.ofInt(1f, 500);
PropertyValuesHolder propertyValuesHolder = PropertyValuesHolder.ofKeyframe("width", kf0, kf1, kf2, kf3, kf4);
mKeyframesObjectAnimator = ObjectAnimator.ofPropertyValuesHolder(mKeyframesObjectAnimationBtn, propertyValuesHolder);
mKeyframesObjectAnimator.setDuration(2000);
mKeyframesObjectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        android.util.Log.d("update", (animation.getAnimatedValue()).toString());
    }
});

动画效果同样是在onAnimationUpdate中添加,上面仅仅是打个log

如果你想应用多个动画,AnimationSet可以帮到你,AnimationSet提供了一个把多个动画组合成一个组合的机制,并可设置组中动画的时序关系,如同时播放,顺序播放等。

如下代码:

mAnimatorSet = new AnimatorSet();
mAnimatorSet.play(mObjectAnimator).before(mValueAnimator);
mAnimatorSet.play(mValueAnimator).before(mKeyframesObjectAnimator);

play是播放,before是在当前动画之前播放,还有2个方法with、after,分别是与当前动画同时播放,在当前动画之后播放,效果如下:

上面是三个动画按照一定顺序播放,有时候我们需要比较复杂的动画效果时,这个类会很重要。

四、扩展介绍

interpolator:插值器,代表动画值的变化速度

repeatCount:动画重复执行的次数

repeatMode:动画执行模式,每次动画执行方式是一样还是按照相反方向执行

duration:动画执行时间

evaluator:根据属性的开始、结束值与TimeInterpolation计算出的因子计算出当前时间的属性值

参考文章:

http://www.cnblogs.com/angeldevil/archive/2011/12/02/2271096.html

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

源码:

https://github.com/taothreeyears/animation

时间: 2024-07-29 01:47:28

Android动画全解的相关文章

android动画详解三 动画API概述

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

android动画详解四 创建动画

· 使用ValueAnimator进行动画 通过指定一些int, float或color等类型的值的集合,ValueAnimator 使你可以对这些类型的值进行动画.你需通过调用ValueAnimator 的某个工厂方法来获得一个ValueAnimator 对象,比如:ofInt(), ofFloat(), 或 ofObject().例如: ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f); animation.setDuration

android动画详解六 XML中定义动画

动画View 属性动画系统允许动画View对象并提供很多比view动画系统更高级的功能.view动画系统通过改变绘制方式来变换View对象,view动画是被view的容器所处理的,因为View本身没有要操控的属性.结果就是View被动画了,但View对象本身并没有变化.在Android3.0中,新的属性和相应的getter和setter方法被加入以克服此缺点. 属性动画系统可以通过改变View对象的真实属性来动画Views.而且,View也会在其属性改变时自动调用invalidate()方法来刷

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

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

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

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

Android 动画详解

这次主要就介绍android动画,android动画目前分为三种形式,Tween Animation 这个只能应用于view对象上面的,Drawable Animation这个是帧动画,就是类似我们有一些列的图片依次播放图片时出现的动画,Property Animation 这个是属性动画,这也是在android3.0之后引进的动画,在手机的版本上是android4.0就可以使用这个动画,下面我们主要就是针对这三种情况进行介绍. Tween Animation 这个动画在Property Ani

Android动画详解

一.动画类型 Android的animation由四种类型组成:alpha.scale.translate.rotate XML配置文件中 alpha 渐变透明度动画效果 scale 渐变尺寸伸缩动画效果 translate 画面转换位置移动动画效果 rotate 画面转移旋转动画效果 Java Code代码中 AlphaAnimation 渐变透明度动画效果 ScaleAnimation 渐变尺寸伸缩动画效果 TranslateAnimation 画面转换位置移动动画效果 RotateAnim

android动画详解一 概述

动画和图形概述 Android 提供了大量的强大的API以应用于UI动画和绘制2D和3D图形.下面各节向你描述了这些API的预览和系统能力以帮助你决定怎么才是达到你需求的最佳方法. 动画 Android 框架提供了两个动画系统: 两种动画系统都是切实可用的,但是一般情况下属性动画系统是被首推使用的.因为它更灵活并且提供了更多的特性.在此两系统之外,你还可以使用Drawable动画,它使得你可以加载drawable资源并且一帧帧的显示它们. Property动画 从Android 3.0 (API

android 动画详解(二)

下面就开始学习属性动画的基本用法,我们来看属性动画的继承关系,如下如所示: 显然关注的焦点应该是ValueAnimator,ObjectAnimator这两个类啦,ObjectAnimator继承自ValueAnimator,是属性动画中非常重要的一个实现类,通过ObjectAnimator类的静态欧工厂方法来创建ObjectAnimator对象,这些静态工厂方法包括:ObjectAnimator.ofFloat(),ObjectAnimator.ofInt()等等,当然最为重要的一个静态工厂方