Android 动画——Frame Animation与Tween Animation

  很多手机应用的引导页都是动画的,添加动画后的应用画面会更加生动灵活,今天博主也学习了Android中Animation的使用,下面来总结下。
  Android中的Animation分为两种,一种是Frame Animation逐帧动画,一种是Tween Animation补间动画。

Frame Animation逐帧动画

  逐帧动画,顾名思义就是定义画面播放的每一帧画面,然后Android按照顺序依次显示。逐帧动画与放电影的原理是相同的。下面我们来看逐帧动画实现的具体步骤:
1. 首先在res文件下建立一个anim的文件夹,这个文件夹是专门用于存放Animation相关的xml文件的。
2. 在anim文件夹下创建一个animation_frame.xml的文件。该文件用于存放播放的每一帧画面。

<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">

    <item android:drawable="@mipmap/aa" android:duration="500"/>
    <item android:drawable="@mipmap/bb" android:duration="500"/>
    <item android:drawable="@mipmap/cc" android:duration="500"/>
    <item android:drawable="@mipmap/dd" android:duration="500"/>
    <item android:drawable="@mipmap/ee" android:duration="500"/>
    <item android:drawable="@mipmap/ff" android:duration="500"/>
    <item android:drawable="@mipmap/gg" android:duration="500"/>
    <item android:drawable="@mipmap/hh" android:duration="500"/>

</animation-list>

  <animation-list></animation-list>为动画的标签,我们在这个标签内通过定义<item/>项,来定义动画显示的每一个画面。<animation-list > 标签中android:oneshot="false" 这是一个非常重要的属性,默认为false 表示 动画循环播放, 如果这里写true 则表示动画只播发一次。<item/>标签内的android:drawable用来定义画面图片,android:duration定义画面的显示时长。

3. 在Activity的xml布局中定义两个按钮用于开始和停止播放控制,一个ImageView用于显示动画。在ImageView中通过设置设置背景引入我们刚才写的animation_frame.xml动画文件。

<LinearLayout 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:orientation="vertical"
    tools:context="com.example.administrator.myanimation.FrameAnimationDemo">

    <Button
        android:id="@+id/button_play"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="开始播放" />

    <Button
        android:id="@+id/button_stop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="停止播放" />

    <ImageView
        android:id="@+id/imageview_frame"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@anim/animation_frame" />
</LinearLayout>

4. 在Activity中获得布局中相关控件的对象,并定义动画,具体如下:

public class FrameAnimationDemo extends Activity implements View.OnClickListener {
    private Button mButtonPlay;//是定义停止按钮
    private Button mButtonStop;//定义开始按钮
    //定义显示动画的ImageView
    private ImageView mImageViewShow;
    //定义逐帧动画
    private AnimationDrawable animationDrawable;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_frame_animation_demo);
        mButtonPlay = (Button) findViewById(R.id.button_play);//开始按钮
        mButtonStop = (Button) findViewById(R.id.button_stop);//停止按钮
        //获得ImageView的对象
        mImageViewShow = (ImageView) findViewById(R.id.imageview_frame);
        //通过ImageView获得逐帧动画的对象
        animationDrawable = (AnimationDrawable) mImageViewShow.getBackground();
        //设置点击事件
        mButtonPlay.setOnClickListener(this);
        mButtonStop.setOnClickListener(this);
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button_play:
                Log.d("data", "开始播放");
                animationDrawable.start();//开始播放
                break;
            case R.id.button_stop:
                Log.d("data", "开始播放");
                animationDrawable.stop();//停止播放
                break;
            default:
                break;
        }
    }
}

  逐帧动画使用AnimationDrawanle,通过ImageView对象的getBackgroud()方法获得AnimationDrawanle对象,然后调用start()方法开始播放动画,调用stop()方法停止播放动画。当然在逐帧动画还可以通过addFrame(Drawable frame, int duration)方法添加每一帧的画面,而不是定义animation_frame.xml文件。

AnimationDrawanle就是用来控制逐帧动画的,他还提供了很多其他的方法进行操作(以下是常用的一部分):

start(); 开始这个动画
stop(); 结束这个动画
setAlpha(100);设置动画的透明度, 取值范围(0 - 255)
setOneShot(true); 设置单次播放
setOneShot(false); 设置循环播放
isRunning(); 判断动画是否正在播放
getNumberOfFrames(); 得到动画的帧数。

这里写图片描述

Tween Animation补间动画

  补间动画与逐帧动画的区别是补间动画不用自己去定义动画的每一帧变化,我们只需要指定动画的第一帧和最后一帧的关键帧即可,其中间的中间帧由系统自己去计算。
  Tween Animation动画中可以定义动画移动、放大、缩小以及产生透明度的变化,我们自己指定动画的两个关键帧以及动画的变化方式,然后系统自己去计算动画的中间变化和轨迹,也就是我们动画的中间过程全是由系统帮我们完成的。这样导致了一个缺点就是我们不容一区控制动画的变化,所以在很多游戏的开发中不会用到补间动画。下面,我们来学习一下补间动画的使用。
  补间动画Tween Animation通过使用Animation来使用,我们首先来看一下Animation:
这里写图片描述

Animation包含5个子类:
AlphaAnimation:透明度改变的动画,通过指定动画开始的透明度和结束的透明度,以及动画 维持的时间。其中透明度是从0到1定义的。
RotateAnimation:旋转的动画,通过指定动画开始时的旋转角度和结束时的旋转角度来定义动画的旋转。
ScaleAnimation:缩放的动画,通过指定动画X,Y轴的缩放,来对动画进行缩放。
TranslateAnimation :平移的动画,通过定义动画在X, Y轴上的平移量来定义动画的平移。
AnimationSet:混合的动画,将以上动画效果混合形成的动画效果。

  下面我们分别来看5种动画效果的实现,首先定义一个Activity的布局文件,在布局文件中定义5个按钮分别实现 AlphaAnimation, AnimationSet, RotateAnimation, ScaleAnimation, TranslateAnimation 动画,定义一个ImageView,显示动画效果。

<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"
    tools:context=".MainActivity">

    <LinearLayout
        android:id="@+id/layout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center">

        <Button
            android:id="@+id/button_start_alpha"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="透明动画" />
        <Button
            android:id="@+id/button_start_translate"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="平移动画" />
        <Button
            android:id="@+id/button_start_rotate"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="旋转动画" />
        <Button
            android:id="@+id/button_start_scale"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="缩放动画" />

    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/layout1">
        <Button
            android:id="@+id/button_start_set"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="混合动画"/>
    </LinearLayout>


    <ImageView
        android:id="@+id/imageview"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@mipmap/ic_launcher"
        android:layout_gravity="center"
        android:layout_centerInParent="true"/>

</RelativeLayout>

AlphaAnimation:

1. 创建一个AlphaAnimation的对象。AlphaAnimation有如下构造器:

  • AlphaAnimation(Context context, AttributeSet attrs)
      该构造器由于加载res文件夹anim文件夹中的xml配置时使用。
  • AlphaAnimation(float fromAlpha, float toAlpha)
      该构造器用于直接定义该动画变化的透明度,从fromAlpha变化到toAlpha。范围为0到1。
      
      这里我们使用第二个构造器。
    2. 设置AlphaAnimation对象动画的显示时间。通过调用setDuration(long durationMillis)方法。
    3. ImageView对象调用startAnimation(Animation animation)方法开始显示动画。
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.button_start_alpha:
                mImageView.setImageResource(R.mipmap.ic_launcher);//设置画面显示
                //透明动画
                AlphaAnimation animation = new AlphaAnimation(0.0f, 1.0f);
                animation.setDuration(5000);//动画播放5秒
                mImageView.startAnimation(animation);
                break;
                default:
                break;
        }
    }

这里写图片描述

TranslateAnimation:

  在平移动画按钮的点击事件中定义如下:
1. 创建一个TranslateAnimation的对象。TranslateAnimation有如下构造器:

  • TranslateAnimation(Context context, AttributeSet attrs)
      该构造器由于加载res文件夹anim文件夹中的xml配置时使用。
  • TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)
      该构造器用于直接定义该动画变化的位移,X轴从fromXDelta变化到toXDelta,Y轴从fromYDelta变化到toYDelta。
  • TranslateAnimation (int fromXType, float fromXValue, int toXType, float toXValue, int fromYType, float fromYValue, int toYType, float toYValue)
      该构造器也是用于直接定义该动画变化的位移,fromXType是指后面fromXValue的数值是现对于自己的还是相对于父布局的,它有两个值:Animation.RELATIVE_TO_SELF, Animation.RELATIVE_TO_PARENT。后面的也是如此,座标的变化是:X轴从fromXValue变化到toXValue,Y轴从fromYValue变化到toYValue。

      这里我们使用第二个构造器。
    2. 设置TranslateAnimation 对象动画的显示时间。通过调用setDuration(long durationMillis)方法。
    3. ImageView对象调用startAnimation(Animation animation)方法开始显示动画。

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.button_start_alpha:
                mImageView.setImageResource(R.mipmap.ic_launcher);//设置画面显示
                 TranslateAnimation animationTranslate = new TranslateAnimation(0, 2 * mImageView.getMeasuredWidth(), 0,
                        2 * mImageView.getMeasuredHeight());              
                animationTranslate.setDuration(5000);//动画播放5秒
                mImageView.startAnimation(animationTranslate);
                break;
                default:
                break;
        }
    }

这里写图片描述

RotateAnimation :

  在旋转动画按钮的点击事件中定义如下:
1. 创建一个RotateAnimation 的对象。RotateAnimation 有如下构造器:

  • RotateAnimation(Context context, AttributeSet attrs)
      该构造器由于加载res文件夹anim文件夹中的xml配置时使用。
  • RotateAnimation(float fromDegrees, float toDegrees)
      该构造器用于直接定义该动画旋转的角度,从fromDegrees变化到toDegrees。
  • RotateAnimation (float fromDegrees, float toDegrees, float pivotX, float pivotY)
      该构造器用于直接定义该动画旋转的角度和旋转的中心,以(pivotX,pivotY)为中心从fromDegrees变化到toDegrees。
  • RotateAnimation (float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
      该构造器用于直接定义该动画旋转的角度和旋转的中心,以(pivotXValue,pivotYValue)为中心从fromDegrees变化到toDegrees。旋转中心的定义有两种类型:Animation.RELATIVE_TO_SELF, Animation.RELATIVE_TO_PARENT

      这里我们使用第二个构造器。
    2. 设置RotateAnimation 对象动画的显示时间。通过调用setDuration(long durationMillis)方法。
    3. ImageView对象调用startAnimation(Animation animation)方法开始显示动画。

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.button_start_alpha:
                mImageView.setImageResource(R.mipmap.ic_launcher);//设置画面显示
                 //旋转动画
                RotateAnimation animationRoate = new RotateAnimation(0, 360);           
                animationTranslate.setDuration(5000);//动画播放5秒
                mImageView.startAnimation(animationTranslate);
                break;
                default:
                break;
        }
    }

这里写图片描述

ScaleAnimation:

  在缩放动画按钮的点击事件中定义如下:
1. 创建一个ScaleAnimation的对象。ScaleAnimation有如下构造器:

  • ScaleAnimation(Context context, AttributeSet attrs)
      该构造器由于加载res文件夹anim文件夹中的xml配置时使用。
  • ScaleAnimation(float fromX, float toX, float fromY, float toY)
      该构造器用于直接定义该动画缩放的大小,X轴从fromX变化到toX,Y轴从fromY变化到toY。
  • ScaleAnimation(float fromX, float toX, float fromY, float toY, float pivotX, float pivotY)
      该构造器用于直接定义该动动画缩放的大小和缩放的中心,以(pivotX,pivotY)为中心缩放。
  • ScaleAnimation(float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
      该构造器用于直接定义该动动画缩放的大小和缩放的中心,以(pivotX,pivotY)为中心缩放。缩放中心的定义有两种类型:Animation.RELATIVE_TO_SELF, Animation.RELATIVE_TO_PARENT

      这里我们使用第二个构造器。
    2. 设置ScaleAnimation对象动画的显示时间。通过调用setDuration(long durationMillis)方法。
    3. ImageView对象调用startAnimation(Animation animation)方法开始显示动画。

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.button_start_alpha:
                mImageView.setImageResource(R.mipmap.ic_launcher);//设置画面显示
                //缩放动画
                ScaleAnimation animationScale = new ScaleAnimation(0.0f, 1f, 0.0f, 1f);      
                animationTranslate.setDuration(5000);//动画播放5秒
                mImageView.startAnimation(animationTranslate);
                break;
                default:
                break;
        }
    }

这里写图片描述

AnimationSet:

  在混合动画按钮的点击事件中定义如下:
1. 创建一个AnimationSet的对象。AnimationSet有如下构造器:

  • AnimationSet(Context context, AttributeSet attrs)
      该构造器由于加载res文件夹anim文件夹中的xml配置时使用。
  • AnimationSet (boolean shareInterpolator)
      是否共享Interpolator的设置。

      这里我们使用第二个构造器。
    2. 设置AnimationSet对象动画的显示时间。通过调用setDuration(long durationMillis)方法。
    3. ImageView对象调用startAnimation(Animation animation)方法开始显示动画。

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.button_start_alpha:
                mImageView.setImageResource(R.mipmap.ic_launcher);//设置画面显示
                AnimationSet animationSet= new AnimationSet(false);

                //从透明到不透明
                AlphaAnimation animation1 = new AlphaAnimation(0.0f, 1.0f);
                //平移
                TranslateAnimation animation2 = new TranslateAnimation(0,mImageView.getMeasuredWidth(), 0,mImageView.getMeasuredHeight());
                //旋转
                RotateAnimation animation3 = new RotateAnimation(0, 360);
                //缩放
                ScaleAnimation animation4 = new ScaleAnimation(0.0f, 1f, 0.0f, 1f);
                //为混合动画添加效果
                animationSet.addAnimation(animation1);
                animationSet.addAnimation(animation2);
                animationSet.addAnimation(animation3);
                animationSet.addAnimation(animation4);

                animationSet.setDuration(10000);//动画播放10秒
                animationTranslate.setDuration(5000);//动画播放5秒
                mImageView.startAnimation(animationTranslate);
                break;
                default:
                break;
        }
    }

这里写图片描述

XML设置动画:

  有时候我们会感觉在java代码中设置代码会使代码看起来更加复杂和庞大,那么为了减少java代码的附中,我们可以将对于动画的设置提升成一个xml文件。这里我们以缩旋转为例定义:
1. 首先在res文件夹下建立一个anim文件夹。
2. 在anim文件夹下创建一个animation_rotate.xml文件。
  这里定义了动画的时间,开始角度,结束角度,以及旋转的中心和重复的次数。注意:repeatCount值为:-1时,循环旋转;0时, 旋转一次;1时旋转2次……以此类推。

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator">
    <rotate
        android:duration="3000"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatCount="1"
        android:toDegrees="360"></rotate>
</set>

3. 在Activity中加载animation_rotate.xml文件,AnimationUtils.loadAnimation()方法加载
  使用AnimationUtils.loadAnimation()方法加载返回一个Animation的对象。

//使用在AnimationUtils.loadAnimation()方法加载。
Animation animationRotate = AnimationUtils.loadAnimation(this, R.anim.animation_rotate);
mImageView.startAnimation(animationRotate);

这里写图片描述

发布了134 篇原创文章 · 获赞 134 · 访问量 38万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章