天天看点

Android动画框架(一)----视图动画&帧动画

转载请注明出处:http://blog.csdn.net/fishle123/article/details/50668189

Android提供三种形式动画:视图动画,帧动画,属性动画。其中属性动画的功能最强大,在Android 3.0中开始引入。本文介绍视图动画和帧动画的使用技巧。

1 视图动画(View Animation)

Android的视图动画可以完成一系列的补间动画(Tween Animation),如平移,缩放,旋转,透明度变化等。视图动画是针对View的内容(content),因此,当View发生视图动画后,其响应事件的位置还是在动画之前的地方,视图动画仅仅改变的是View的内容的展示(如针对Button的平移动画,将Button的中心从A点移动到B点,动画完成后Button在B点显示,但如果要点击Button,还是得点A点区域,而不是点B点区域)。Android提供两种方式来定义动画:XML和Android Code(写代码的形式),推荐使用XML方式,因为可读性更好。下面分别介绍这两种视图动画的使用:

1.1 XML方式

XML定义视图动画的语法如下:

<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@[package:]anim/interpolator_resource"
    android:shareInterpolator=["true" | "false"] >
<alpha
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:fromAlpha="float"
        android:toAlpha="float" />
    <scale
        android:fromXScale="float"
        android:toXScale="float"
        android:fromYScale="float"
        android:toYScale="float"
        android:pivotX="float"
        android:pivotY="float" />
    <translate
        android:fromXDelta="float"
        android:toXDelta="float"
        android:fromYDelta="float"
        android:toYDelta="float" />
    <rotate
        android:fromDegrees="float"
        android:toDegrees="float"
        android:pivotX="float"
        android:pivotY="float" />
    <set>
        ...
    </set>
</set>
           

<alpha>, <scale>, <translate>, <rotate>四个标签分别对应透明度、缩放、平移、旋转四种形式的视图动画,<set>用来定义一组或多组动画,它们分别对应AlphaAnimation,ScaleAnimation,TranslateAnimation,RotateAnimation,AnimationSet五个类。下面介绍几个重要的属性:

<set>标签

1)android:interpolator----动画集合使用的差值器,如线性差值器(如平移动画中X坐标随时间线性变化),默认为@android:anim/accelerate_decelerate_interpolator,即加速减速差值器;

2)android:shareInterpolator----它的值是一个boolean值,表示集合中的动画是否共享同一个差值器。如果不共享同一个差值器,每个动画可以定义自己的使用的差值器。

系统提供的差值器如下表,当然我们也可以定义自己的差值器。

Interpolator class Resource ID
AccelerateDecelerateInterpolator @android:anim/accelerate_decelerate_interpolator
AccelerateInterpolator @android:anim/accelerate_interpolator
AnticipateInterpolator @android:anim/anticipate_interpolator
AnticipateOvershootInterpolator @android:anim/anticipate_overshoot_interpolator
BounceInterpolator @android:anim/bounce_interpolator
CycleInterpolator @android:anim/cycle_interpolator
DecelerateInterpolator @android:anim/decelerate_interpolator
LinearInterpolator @android:anim/linear_interpolator
OvershootInterpolator @android:anim/overshoot_interpolator

<alpha>标签

1)android:fromAlpha----float类型,表示透明度alpha的起始值,如0表示完全透明,1表示不透明;

2)android:toAlpha----float类型,表示透明度alpha的结束值。

<scale>标签

1)android:fromXScale---float类型,水平方向缩放起始值,1表示不做缩放;

2)android:toXScale----float类型,水平方向缩放结束值;

3)android:fromYScale----float类型,竖直方向缩放结束值;

4)android:toYScale----float类型,竖直方向缩放结束值;

5)android:pivotX----float类型,缩放的轴点的x坐标,默认为view的中心点;

6)android:pivotY----float类型,缩放的轴点y坐标,默认为view的中心点;

<translate>标签

1)android:fromXDelta----float或百分比,x方向的起始偏移量。如果是float类型,则偏移量以pixel为单位,是一个绝对值。如果是百分比(如10%),表示相对于element的width,如10%表示偏移量为width的10%,取值范围-100%--100%。如果是10%p,表示偏移量为parent父窗口的width的10%;

2)android:toXDelta----float或百分比,x方向的结束偏移量,取值与fromXDelta类似;

3)android:fromYDelta----float或百分比,y方向的起始偏移量,取值与fromXDelta类似,但是百分比是相对于height;

4)android:toYDelta----float或百分比,y方向的结束偏移量,取值与fromYDelta类似;

<rotate>标签

1)android:fromDegrees----float,旋转的起始角度,单位是degree;

2)android:toDegrees----float,旋转的结束角度,单位是degree;

3)android:pivotX----float或百分比,旋转的中心的x坐标。如果是float类型,相对于Object的左边界的距离,以pixel为单位,如5表示距离左边界5个像素的位置。如果是百分比,如10%表示位置相对于Object的width的10%,10%p表示Object的parent的width的10%;

4)android:pivotY----float或百分比,旋转的中心的y坐标。取值与pivotX类似,50%表示中心位置。

下面给出一个例子:

在res目录下新建一个文件夹anim,然后新建一个xml,文件名为tween_anim.xml,内容如下:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false"
    android:fillAfter="true" >
 
    <alpha
        android:duration="700"
        android:fromAlpha="0.2"
        android:toAlpha="1"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
       
        />
 
    <set android:interpolator="@android:anim/decelerate_interpolator" >
        <scale
            android:duration="4000"
            android:fromXScale="1.4"
            android:fromYScale="0.6"
            android:pivotX="50%"
            android:pivotY="50%"
            android:toXScale="2"
            android:toYScale="2" />
 
        <rotate
            android:duration="4000"
            android:fromDegrees="0"
            android:pivotX="50%"
            android:pivotY="50%"
            android:toDegrees="-45" />
        <translate
            android:fromXDelta="0"
            android:toXDelta="200"
            android:duration="4000"
            android:fromYDelta="0"
            android:toYDelta="200"/>
    </set>
 
</set>
           

这样就完成了一个视图动画的定义,然后在MainActivity中使用这个动画:

mTextView = (TextView)findViewById(R.id.textView1);

mAnimation = AnimationUtils.loadAnimation(this, R.anim.tween_anim);

mTextView.startAnimation(mAnimation);

效果如下:

Android动画框架(一)----视图动画&amp;帧动画

1.2 Android code方式

上面有提到Android提供了AlphaAnimation,ScaleAnimation,TranslateAnimation,RotateAnimation,AnimationSet五个类来帮助我们实现视图动画,它们分别对应透明度东湖,缩放动画,平移动画,旋转动画和动画集合。上面的动画效果如果使用代码的方式,可以如下实现:

AlphaAnimation al = new AlphaAnimation(0.2f, 1);
al.setDuration(700);
al.setInterpolator(new AccelerateDecelerateInterpolator());
ScaleAnimation sc = new ScaleAnimation(1.4f, 2f,0.6f, 2f, Animation.RELATIVE_TO_SELF,0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
RotateAnimation ro = new RotateAnimation(0, -45, Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
TranslateAnimation tr= new TranslateAnimation(0, 200, 0, 200);
boolean shareInterpolator0 = true;
AnimationSet set0 = new AnimationSet(shareInterpolator0);
set0.setDuration(4000);
set0.setInterpolator(new DecelerateInterpolator());
set0.addAnimation(sc);
set0.addAnimation(ro);
set0.addAnimation(tr);
boolean shareInterpolator1 = false;
AnimationSet set1 = new AnimationSet(shareInterpolator1);
set1.addAnimation(al);
set1.addAnimation(set0);
view.startAnimation(set1);
           

对于Animation事件,Android提供了Animation.AnimationListener接口来接收事件通知。如果监听相应的事件,代码如下:

animation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
}
});
           

2 帧动画(FrameAnimation)

帧动画也称为Drawable Animation,帧动画用来播放一系列的Drawable,就像放电影一样。与视图动画不同,Android提供了AnimationDrawable类来使用帧动画,它是Drawable的子类,同时实现了Animatable接口,所以也具有动画功能。同样的,帧动画也可以使用XML和code两种方式来实现,不过使用XML更直观,更简单,推荐使用XML方式。下面分别介绍两种实现方式。

2.1 XML方式

XML定义帧动画语法如下:

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot=["true" | "false"] >
    <item
        android:drawable="@[package:]drawable/drawable_resource_name"
        android:duration="integer" />
</animation-list>
           

<animation-list>

标签定义一个帧动画,它是帧动画的根节点。包含一个或多个<item>

1)android:oneshot----boolean类型,true表示只播放一次动画,false表示循环播放动画。

<item>

定义一帧动画,必须作为<animation-list>的子节点。

1)android:drawable----drawable资源,即要在这一帧中展示的内容;

2)android:duration----integer,该帧展示的时间,单位是毫秒milliseconds。

下面给出一个例子:

先在res/anim目录下新建color_show.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/frame0"
        android:duration="1000"/>
    <item
        android:drawable="@drawable/frame1"
        android:duration="1000"/>
    <item
        android:drawable="@drawable/frame2"
        android:duration="1000"/>
 
</animation-list>
           

然后在MainActivity中使用这个动画:

ImageView imageView = (ImageView)findViewById(R.id.imageView);
imageView.setBackgroundResource(R.drawable.color_show);
AnimationDrawable drawable = (AnimationDrawable)imageView.getBackground();
drawable.start();
           

动画效果如下图:

Android动画框架(一)----视图动画&amp;帧动画

帧动画比较容易引起OOM,所以在使用帧动画的时候应该尽量避免使用太多尺寸较大的图片。

2.2 Android code方式

与视图动画不同,Android提供了AnimationDrawable类来使用帧动画,它并不是Animation的子类,而是Drawable的子类,同时实现了Animatable接口,所以也具有动画功能。同样的,上面的动画效果如果使用Android code方式,可以如下实现:

Resources  resources = getResources();
Drawable frame0= resources.getDrawable(R.drawable.frame0);
Drawable frame1=resources.getDrawable(R.drawable.frame1);
Drawable frame2=resources.getDrawable(R.drawable.frame2);
AnimationDrawable drawable = new AnimationDrawable();
int duration = 1000;
drawable.addFrame(frame0, duration);
drawable.addFrame(frame1, duration);
drawable.addFrame(frame2, duration);
imageView.setBackgroundDrawble(drawable);//view.setBackground(drawable);
drawable.setOneShot(false);
drawable.start();
           

有一点需要注意,AnimationDrawable的start方法不能在Activity的onCreate方法中调用,因为这个时候AnimationDrawable还没有完全attached到window上(可能还没有调用ViewManager的addView来将Decoriew添加到PhoneWindow)。如果不需要任何交互就立即开始播放动画,可以在Activity的onWindowFocusChanged()方法中调用AnimationDrawable的start方法开始播放。

3 总结

到此为止,视图动画和帧动画的使用总结完毕。这里需要记住的是:视图动画是针对View的内容(content),因此,当View发生视图动画后,其响应事件的位置还是在动画之前的地方,视图动画仅仅改变的是View的内容的展示。

如果大家对动画感兴趣,可以阅读我的动画相关的其他文章,看完这些文章相信大多数动画相关的问题都能解决了。

Android动画框架(二)----属性动画

Android动画框架(三)----布局动画&Activity过渡动画