欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android进阶知识(十八):View动画、帧动画与View动画的特殊应用

程序员文章站 2024-03-26 08:12:47
...

Android进阶知识(十八):View动画、帧动画与View动画的特殊应用

  Android的动画可以分为三种:View动画、帧动画和属性动画,其实帧动画也属于View动画的一种,只不过它和平移、旋转等常见的View动画在表现形式上略有不同。

一、View动画

  View动画作用对象为View,其通过对场景里的对象不断做图形变换(平移、旋转、缩放、透明度)从而产生动画效果,它是一种渐近式动画,并且View动画支持自定义。

  1. View动画的种类

  View动画的四种变换效果对应着Animation的四个子类:TranslateAnimation、ScaleAnimation、RotateAnimation和AlphaAnimation。如下表所示,这四种动画既可以通过XML来定义,也可以通过代码来定义,对于View动画来说,由于XML格式的动画可读性更好,因此建议采用XML定义

名称 标签 子类 效果
平移动画 <translate> TranslateAnimation 移动View
缩放动画 <scale> ScaleAnimation 放大或缩小View
旋转动画 <rotate> RotateAnimation 旋转View
透明度动画 <alpha> AlphaAnimation 改变View的透明度

  通过XML文件创建的动画,其文件路径为:res/anim/filename.xml。View动画的描述文件有固定的语法,如下所示。

<?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: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>

  从上面的语法可以看出,View动画既可以是单个动画,也可以由一系列动画组成。<set>标签表示动画集合,对于AnimationSet类,它可以包含若干个动画,并且它的内部也可以嵌套其他动画集合。至于各个属性的的含义具体可以参照博客:Android View动画——alpha、scale等属性用法
  定义了XML动画,应用动画的代码如下所示。

Button mButton = findViewById(R.id.button);
Animation animation = AnimationUtils.loadAnimation(this, R.anim.animations);
mButton.startAnimation(animation);

  除了在XML中定义动画外,还可以通过代码来应用动画,一个例子如下所示。

AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1);
alphaAnimation.setDuration(300);
mButton.startAnimation(alphaAnimation);

  另外,通过Animation的setAnimationListener方法可以给View动画添加过程监听,接口如下所示。

public static interface AnimationListener {
    void onAnimationStart(Animation animation);
    void onAnimationEnd(Animation animation);
    void onAnimationRepeat(Animation animation);
}
  1. 自定义View动画

  自定义View动画是一件既简单又复杂的事情。
  简单在于,派生一种新动画只需要继承Animation这个抽象类,然后重写它的initialize和applyTransformation方法,在initialize方法中做一些初始化工作,在applyTransformation中进行相应的矩阵变换即可,很多时候需要采用Camera来简化矩阵变换的过程。
  说其复杂,在于自定义View动画的过程主要是矩阵变换的过程,而矩阵变换是就会比较复杂。具体可以参考博客:Android View动画——自定义View动画
Android进阶知识(十八):View动画、帧动画与View动画的特殊应用

二、帧动画

  帧动画通过顺序播放一系列图形从而产生动画效果。
  不同于View动画,系统提供了另一个类AnimationDrawable来使用帧动画。帧动画的使用需要先通过XML来定义一个AnimationDrawable,如下所示。

// res/drawable/frame_animation.xml
<?xml version="1.0" enconding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false" >
    <item android:drawable="@drawable/image1" android:duration="500" />
    <item android:drawable="@drawable/image2" android:duration="500" />
    <item android:drawable="@drawable/image3" android:duration="500" />
</animation-list>

  将上述的Drawable作为View的背景并通过Drawable来播放动画即可。

Button mButton = findViewById(R.id.button);
mButton.setBackgroundResource(R.drawable.frame_animation);
AnimationDrawable drawable = (AnimationDrawable)mButton.getBackground();
drawable.start();

  帧动画的使用比较简单,但是比较容易引起OOM,所以在使用帧动画时应尽量避免使用过多尺寸较大的图片
Android进阶知识(十八):View动画、帧动画与View动画的特殊应用

三、View动画的特殊应用

  View动画除了四种形式之外,还可以在一些特殊情景下使用,比如在ViewGroup中可以控制子元素的出场效果,在Activity中可以实现不同Activity之间的切换效果。

  1. LayoutAnimation

  LayoutAnimation作用于ViewGroup,为ViewGroup指定一个动画,使其子元素的出场具有动画效果(通常作用于ListView上)。LayoutAnimation为ViewGroup的子元素添加出场效果的步骤如下。

  • 定义LayoutAnimation,代码如下。
// res/anim/anim_layout.xml
<layoutAnimation
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:delay="0.5"
    android:animationOrder="normal"
    android:animation="@anim/anim_item" />

  属性说明:

属性 描述
android:delay 表示子元素开始动画的延迟,比如子元素入场动画的时间周期为300ms,那么0.5表示每个子元素依次延迟150ms播放入场动画,第一个延迟150ms,第二个延迟300ms。
android:animationOrder 表示子元素动画的顺序,有normal、reverse和random。normal表示顺序显示;reverse表示逆向显示;randoom表示随机播放入场动画。
android:animation 为子元素指定具体的入场动画
  • 为子元素指定具体的入场动画,如下所示。
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="300"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:shareInterpolator="true" >
    <alpha
        android:fromAlpha="0.0"
        android:toAlpha="1.0" />
   <translate
       android:fromXDelta="500"
       android:toXDelta="0" />
</set>
  • 为ViewGroup指定android:layoutAnimation属性,如下所示。
<ListView
    android:id="@+id/list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layoutAnimation="@anim/anim_layout"
    android:background="#fff4f7f9" />

  除了在XML中指定LayoutAnimation之外,还可以通过LayoutAnimationController来实现,具体代码如下。

ListView listView = layout.findViewById(R.id.list);
Animation animation = AnimationUtils.loadAnimation(this, R.anim.anim_item);
LayoutAnimationController controller = new LayoutAnimationController(animation);
controller.setDelay(0.5f);
controller.setOrder(LayoutAnimatinoController.ORDER_NORMAL);
listView.setLayoutAnimation(controller);
  1. Activity的切换效果

  Activity有默认的切换效果,但是这个效果可以自定义,主要用到overridePendingTransition(int enterAnim, int exitAnim)这个方法,这个方法必须在startActivity(Intent)或者finish()之后被调用才能生效,参数含义如下。

  • enterAnim——Activity被打开时,所需的动画资源id。
  • exitAnim——Activity被暂停时,所需的动画资源id。

  添加自定义切换效果的代码如下所示。

// Activity启动指定切换效果
Intent intent = new Intent(this, TestActivity.class);
startActivity(intent);
overridePendingTransition(R.anim.enter_anim, R.anim.exit_anim);

// Activity退出指定切换效果
@Override
public void finish() {
    super.finish();
   overridePendingTransition(R.anim.enter_anim, R.anim.exit_anim);
}

  需要注意的是,overridePendingTransition这个方法必须位于startActivity或者finish的后面,否则动画效果将不起作用
Android进阶知识(十八):View动画、帧动画与View动画的特殊应用

参考资料:《Android开发艺术探索》