Android补间动画

本文详细介绍了Android中的补间动画和帧动画。补间动画包括XML和Java代码形式,涉及平移、缩放、旋转和透明度四种效果,但存在作用对象局限性和动画效果单一等问题。帧动画则是按照顺序播放一组图片,通过animation-list和item标签在XML中定义,或者使用AnimationDrawable在Java代码中实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述

本篇博客基于《Android开发艺术探索》,将会介绍以下两种动画:

  • 补间动画
  • 帧动画

事实上帧动画也是补间动画的一种,但是它们的使用方式略有不同,所以将它们分开介绍。


一、补间动画

补间动画(Tween animation)也叫做View动画,因为它的作用对象是View,它支持平移、缩放、旋转和透明度四种变换效果,它们的具体描述如下表所示:

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

补间动画的创建有两种形式:XML文件和代码形式,下面分别介绍它们。

1. XML文件形式

XML文件形式即通过在XML文件中设置相关属性来达到动画的效果,需要特别注意的是动画相关的XML文件必须放置在 res/anmi/ 文件夹中,如下图所示:
在这里插入图片描述

1.1 set标签

刚创建的文件如下所示:

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

</set>

可以看到有一个 <set> 标签,表示的是动画集合,它可以包含若干个动画,并且其内部也是可以嵌套其他动画集合的。它有两个可指定的属性值如下:

属性描述
interpolator表示动画集合所采用的插值器,默认为加减速插值器
shareInterpolator表示集合中的动画是否和集合共享同一个插值器。如果集合不指定插值器,那么子动画就需要单独指定所需的插值器或使用默认值

例子:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:shareInterpolator="false">
	......
</set>

在这个例子中 intercepolator 设置为 @android:anim/accelerate_decelerate_interpolator,即默认值,如果不设置该属性达到的效果也是一样的。将 shareInterpolator 属性设置为 false 表示集合中的动画不和集合共享同一插值器。

1.2 translate标签

<translate>标签用于控制平移动画,它可以使一个View在水平/竖直方向上完成平移的动画效果,它的一系列属性含义如下表所示:

属性描述
fromXDelta表示 x 的起始值
toXDelta表示 x 的结束值
fromYDelta表示 y 的起始值
toYDelta表示 y 的结束值

其中,各个属性有如下三种取值类型可供选择:

类型描述
float当取值为浮点类型的数值时,表示为绝对值类型,默认以px为单位
%相对自身的百分比取值,表示以当前View的宽度或高度为基数计算
%p相对父布局的百分比取值,表示以父视图的宽度或高度为基数计算

平移动画的起始点为View的左上角位置,如下图所示:

在这里插入图片描述

例子:

<translate
    android:duration="100"
    android:fromXDelta="0.5"
    android:toXDelta="100.5"
    android:fromYDelta="0.5"
    android:toYDelta="100.5" />

该例子表示View从 (0.5, 0.5) 的位置平移到 (100.5, 100.5) 的位置,动画时间为100ms。

1.3 scale标签

<scale>标签表示缩放动画,它可以使View具有放大/缩小的效果,它的一系列属性含义如下表所示:

属性描述
fromXScale水平方向缩放的起始值
toXScale水平方向缩放的结束值
fromYScale竖直方向缩放的起始值
toYScale竖直方向缩放的结束值
pivotX缩放的轴点的 x 坐标
pivotY缩放的轴点的 y 坐标

例子:

<scale
    android:duration="500"
    android:fromXScale="0.5"
    android:toXScale="1.5"
    android:fromYScale="0.5"
    android:toYScale="1.5"/>

这个例子是将View从原来的0.5倍放大到原来的1.5倍,动画时间是500ms。缩放轴点为View左上角(默认情况下),如果想以View中心为轴点,可以做如下设置:

<scale
    android:duration="500"
    android:fromXScale="0.5"
    android:toXScale="1.5"
    android:fromYScale="0.5"
    android:toYScale="1.5"
    android:pivotX="50%"
    android:pivotY="50%"/>

其中轴点的取值方式也有三种类型可供选择:浮点型数字、相对自身的百分号%和相对父布局的百分比%p,这三种类型的含义在 translate 部分已经说过,这里不再赘述。

1.4 rotate标签

<rotate>标签表示旋转动画,它可以使View具有旋转的效果,它的一系列属性含义如下表所示:

属性描述
fromDegrees旋转开始的角度
toDegrees旋转结束的角度
pivotX旋转的轴点的 x 坐标
pivotY旋转的轴点的 y 坐标
<rotate
    android:duration="400"
    android:fromDegrees="0.0"
    android:toDegrees="90.0"/>

该例子表示View从0°旋转90°,轴点为View的左上角(默认情况下)。如果想以View中心为轴点的话,可以按如下进行属性设置:

<rotate
    android:duration="400"
    android:fromDegrees="0.0"
    android:toDegrees="90.0"
    android:pivotX="50%"
    android:pivotY="50%"/>

这和缩放动画中轴点的相关设置是一致的,同样可以有三种取值方式:浮点型数值、相对自身的百分比以及相对父布局的百分比,这里不再赘述。

1.5 alpha标签

<alpha>标签表示透明度动画,它可以改变View的透明度,它的一系列属性含义如下表所示:

属性描述
fromAlpha表示透明度的起始值
toAlpha表示透明度的结束值

alpha属性的取值为0.0~1.0。其中0.0表示完全透明,1.0表示完全不透明。

例子:

<alpha
    android:duration="500"
    android:fromAlpha="0.0"
    android:toAlpha="1.0"/>

这个例子表示将View的透明度从完全透明变为完全不透明,动画时间为500ms。

1.6 共有属性

上面所说的为各自标签所特有的属性,它们之间也存在一些共有的属性,如下表所示:

属性描述
duration动画的持续时间,单位为ms
fillAfter动画结束后View是否停留在结束位置,true表示停留在结束位置
startOffset动画执行延迟的时间,单位为ms
interpolator用于控制动画在不同时段的执行速度,默认是加减速插值器
repeatCount动画的重复次数,默认为0,即不重复
repeatMode有两个取值:restart和reverse,reverse表示动画正反轮流执行,restart表示一直从头开始执行
zAdjustment在执行动画过程中调整Z轴的位置,有三个取值可选:normal、top和bottom,默认为normal

前面的XML文件设置完成之后,我们在Java中如何将它们引入相关的View播放动画呢?这就要借助 AnimationUtils#loadAnimation 方法来添加了,例如我们现在要为一个 ImageView 添加动画,代码如下所示:

Animation anim = AnimationUtils.loadAnimation(MainActivity.this, R.anim.anmi_demo);
imageView.startAnimation(anim);

上面就是关于XML形式的简要介绍,接下来我们来了解通过Java代码的形式设置补间动画。

2. Java代码形式

在Java中,translate、scale、rotate、alpha、set分别对应下面的几个类:

  • TranslateAnimation
  • ScaleAnimation
  • RotateAnimation
  • AlphaAnimation
  • AnimationSet

下面分别介绍它们的使用。

2.1 TranslateAnimation

TranslateAnimation 有三个构造方法来创建对象,这三个构造方法的说明如下所示:

public TranslateAnimation(Context context, AttributeSet attrs)
参数含义
context上下文对象
attrsxml中读取的属性设置
public TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)
参数含义
fromXDelta动画开始时x的取值,单位为px
toXDelta动画结束时x的取值,单位为px
fromYDelta动画开始时y的取值,单位为px
toYDelta动画结束时y的取值,单位为px
public TranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue,
        int fromYType, float fromYValue, int toYType, float toYValue)
参数含义
fromXType动画开始时x的取值类型
fromXValue动画开始时x的取值,其取值受fromXType影响
toXType动画结束时x的取值类型
toXValue动画结束时x的取值,其取值受toXType影响
fromYType动画开始时y的取值类型
fromYValue动画开始时y的取值,其取值受fromYType影响
toYType动画结束时y的取值类型
toYValue动画结束时y的取值,其取值受toYType影响

在这个构造方法中,Type 的取值有如下三个,它们的描述如下表所示:

Type描述
Animation.ABSOLUTE取绝对值,所取值表示像素值的大小,单位为px
Animation.RELATIVE_TO_SELF相对自身的百分比取值,所取值表示相对自身长/宽的百分比
Animation.RELATIVE_TO_PARENT相对父布局的百分比取值,所取值表示相对父布局长/宽的百分比

下面我们以 ImageView 从 (0,0) 处平移到 (100,100) 处为例进行代码的示范:

TranslateAnimation anim = new TranslateAnimation(0.0f, 100.0f, 0.0f, 100.0f);
anim.setDuration(1000);
imageView.startAnimation(anim);

2.2 ScaleAnimation

ScaleAnimation有4个构造方法来创建对象,它们的说明如下所示:

public ScaleAnimation(Context context, AttributeSet attrs)
参数含义
context上下文对象
attrsxml中读取的属性设置
public ScaleAnimation(float fromX, float toX, float fromY, float toY)
参数含义
fromXx开始时的缩放比例
toXx结束时的缩放比例
fromYy开始时的缩放比例
toYy结束时的缩放比例
public ScaleAnimation(float fromX, float toX, float fromY, float toY,
        float pivotX, float pivotY)
参数含义
fromXx开始时的缩放比例
toXx结束时的缩放比例
fromYy开始时的缩放比例
toYy结束时的缩放比例
pivotX缩放轴点的x坐标,单位为px
pivotY缩放轴点的y坐标,单位为px
public ScaleAnimation(float fromX, float toX, float fromY, float toY,
        int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
参数含义
fromXx开始时的缩放比例
toXx结束时的缩放比例
fromYy开始时的缩放比例
toYy结束时的缩放比例
pivotXType缩放轴点x的取值类型
pivotXValue缩放轴点的x的取值,其取值受pivotXType影响
pivotYType缩放轴点y的取值类型
pivotYValue缩放轴点的y的取值,其取值受pivotYType影响

其中 Type 的取值同样也有三种:Animation.ABSOULTEAnimation.RELATIVE_TO_SELFAnimation.RELATIVE_TO_PARENT,分别表示像素值、相对自身的百分比取值以及相对父布局的百分比取值。

下面我们还是以ImageView为例,缩放轴点设置为其中点,开始时缩小到原来的0.5倍,然后经过500 ms的时间逐渐扩大到原来的1.5倍,代码如下所示:

ScaleAnimation anim = new ScaleAnimation(0.5f, 1.5f, 0.5f, 1.5f,
        Animation.RELATIVE_TO_SELF, 0.5f,
        Animation.RELATIVE_TO_SELF, 0.5f);
anim.setDuration(500);
imageView.startAnimation(anim);

可以看到我们在这里由于需要取View的中点作为轴点,所以采用相对自身百分比的形式进行取值。

2.3 RotateAnimation

RotateAnimation 同样有4个方法来创建对象,说明如下所示:

public RotateAnimation(Context context, AttributeSet attrs)
参数含义
context上下文对象
attrsxml中读取的属性设置
public RotateAnimation(float fromDegrees, float toDegrees)
参数含义
fromDegrees开始旋转时的角度值
toDegrees旋转结束时的角度值
public RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY)
参数含义
fromDegrees开始旋转时的角度值
toDegrees旋转结束时的角度值
pivotX轴点的x坐标,单位为px
pivotY轴点的y坐标,单位为px
public RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue,
        int pivotYType, float pivotYValue)
参数含义
fromDegrees开始旋转时的角度值
toDegrees旋转结束时的角度值
pivotXType轴点x的取值类型
pivotXValue轴点x的取值,其取值受pivotXType的影响
pivotYType轴点y的取值类型
pivotYValue轴点y的取值,其取值受pivotYType的影响

接下来同样通过一个例子来展示下它的使用,我们还是以ImageView为例,以其中点为轴心旋转90°,代码如下所示:

RotateAnimation anim = new RotateAnimation(0.0f, 90.0f, 
        Animation.RELATIVE_TO_SELF, 0.5f, 
        Animation.RELATIVE_TO_SELF, 0.5f);
anim.setDuration(1000);
imageView.startAnimation(anim);

2.4 AlphaAnimation

AlphaAnimation 应当是这所有动画类型里面最为简单的了,它只有以下两个构造方法:

public AlphaAnimation(Context context, AttributeSet attrs)
参数含义
context上下文对象
attrsxml中读取的属性设置
public AlphaAnimation(float fromAlpha, float toAlpha)
参数含义
fromAlpha动画开始时的透明度,0表示完全透明,1表示完全不透明
toAlpha动画结束时的透明度,0表示完全透明,1表示完全不透明

AlphaAnimation 的应用比较简单,这里就不给出示例了。

2.5 AnimationSet

AnimationSet 和前面的4个类不同,它是用于组合动画的,它有如下两个构造方法:

public AnimationSet(Context context, AttributeSet attrs)
参数含义
context上下文对象
attrsxml中读取的属性设置
public AnimationSet(boolean shareInterpolator)
参数含义
shareInterpolator用于设置是否和集合中的动画共享同一个插值器

在初始化完 AnimationSet 对象之后,我们就可以通过 Animation#addAnimation 方法将动画添加到集合当中了,示例如下所示:

TranslateAnimation translateAnim = new TranslateAnimation(0.0f, 100.0f, 0.0f, 100.0f);
AlphaAnimation alphaAnim = new AlphaAnimation(0.0f, 1.0f);
AnimationSet animSet = new AnimationSet(false);
animSet.addAnimation(translateAnim);
animSet.addAnimation(alphaAnim);
animSet.setDuration(1000);
imageView.startAnimation(animSet);

这个例子将平移动画和透明度动画进行了组合,动画持续时间为1s。以上就是有关补间动画中Java代码形式的所有内容。

3. 开启动画监听

我们还可以通过开启动画监听来处理播放动画启动时、动画结束时、重复播放动画时的相关代码逻辑。动画监听的开启通过调用 Animation#setAnimationListener 方法进行设置,传入的参数为 Animation.AnimationListener,示例如下所示:

TranslateAnimation anim = new TranslateAnimation(0.0f, 100.0f, 0.0f, 100.0f);
anim.setAnimationListener(new Animation.AnimationListener() {
    @Override
    public void onAnimationStart(Animation animation) {
        // 动画启动时回调该方法
    }

    @Override
    public void onAnimationEnd(Animation animation) {
        // 动画播放结束时回调该方法
    }

    @Override
    public void onAnimationRepeat(Animation animation) {
        // 动画重复播放时回调该方法
    }
});

4. 补间动画的不足和缺陷

  • 作用对象的局限性:补间动画的作用对象只能是View,无法对非View的对象进行动画操作。
  • 没有改变View的属性:补间动画只是改变视觉效果,例如将一个按钮移动到某个位置之后,点击移动后的按钮并无响应点击事件,而点击按钮移动前的位置则响应了点击事件,说明View只是改变了视觉效果,并没有改变实际位置。
  • 动画效果单一:补间动画只能出现平移、缩放、旋转、透明度等简单的功能,一旦遇到相对复杂的动画效果,即超出了上述4种动画效果,那么补间动画则无法实现。一旦遇到相对复杂的动画效果,即超出了上述4种动画效果,那么补间动画则无法实现。

5. 补间动画的应用场景

虽然上面对补间动画进行了各个角度和维度的批判,但是补间动画依然有它存在的意义,要不 Google 也不会现在都还对它进行支持。它主要有两种使用场景,下面对它们一一进行介绍。

5.1 LayoutAnimation

LayoutAnimation 的作用对象是 ViewGroup,它可以为 ViewGroup 指定一个动画,这样当它的子元素出场时都会带有这种动画效果。这种效果最常见的使用场景是ListView的进场动画,它同样有XML和Java代码两种使用方式,使用如下所示:

5.1.1 XML文件形式

定义的XML文件毫无疑问也是放在 res/anim/ 文件夹下的,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
	android:delay="0.5"
    android:animation="@anim/anmi_demo"
    android:animationOrder="normal">
</layoutAnimation>

其中,anmi_demo.xml 的代码如下:

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

    <translate
        android:fromXDelta="100%p"
        android:toXDelta="0"/>

    <alpha
        android:fromYDelta="0.0"
        android:toYDelta="1.0"/>
</set>

我们此时需要的标签为 layoutAnimation,它的属性如下表所示:

属性描述
delay子元素开始动画的时间延迟,它是一个百分比的取值,例如取值0.5时,假设子元素的入场动画周期为200ms,那么0.5就表示每个子元素的动画都需要延时100ms后再开启
animation为子元素指定的具体的入场动画
animationOrder一共有三个取值可选:normal、random 和 reverse,normal表示顺序显示,random表示随机显示,reverse表示逆序显示
interpolator插值器设置

在设置完成之后我们需要在相应的ViewGroup中进行属性设置,这里以ListView为例:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layoutAnimation="@anim/anim_list_view"/>

</LinearLayout>

这样我们对ListView子元素的进场动画就设置完成了,效果图如下所示:
在这里插入图片描述
接下来我们看到如何用Java代码的形式实现同样的效果。

5.1.2 Java代码形式

使用Java代码的形式需要借助一个类:LayoutAnimationController,它就相当于XML中的animation-list标签,我们接下来直接看到代码:

Animation anim = AnimationUtils.loadAnimation(this, R.anim.anmi_demo);
LayoutAnimationController controller = new LayoutAnimationController(anim, 0.5f);
controller.setInterpolator(new LinearInterpolator());
controller.setOrder(LayoutAnimationController.ORDER_NORMAL);
mListView.setLayoutAnimation(controller);

最后实现的效果是一样的。

5.2 Activity的切换效果

补间动画除了能为ViewGroup设置动画外,还能为Activity设置切换效果。这里需要借助Activity中的:

 void overridePendingTransition(int enterAnim, int exitAnim)
参数含义
enterAnimActivity被打开时,所需动画的资源id
exitAnimActivity被暂停时,所需动画的资源id

这个方法必须在 startActivity 或者 finish 方法之后调用才能生效,下面是示例代码:

Intent intent = new Intent(MainActivity.this, SecondActivity.class);
startActivity(intent);
overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
@Override
public void finish(){
    super.finish();
    overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
}

其中,fade_in.xmlfade_out.xml 的代码如下所示:

// res/anmi/fade_in.xml
<?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"/>
</set>
// res/anmi/fade_out.xml
<?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="1.0"
    android:toAlpha="0.0"/>
</set>

效果如下所示:
在这里插入图片描述
可以看到,通过调用 overridePendingTransition 方法,我们实现了简单的淡入、淡出效果。

除了Activity之外,Fragment之间的切换也是可以设置相应的动画的。Fragment 有两种,一种是v4包下的,另一种是普通的Fragment,使用方式如下所示:

android.support.v4.app.Fragment

v4包下的Fragment是用过FragmentTransaction#setCustomAnimations来进行动画设置的,这个方法的定义如下所示:

public abstract FragmentTransaction setCustomAnimations(@AnimatorRes @AnimRes int enter,
            @AnimatorRes @AnimRes int exit, @AnimatorRes @AnimRes int popEnter,
            @AnimatorRes @AnimRes int popExit)
参数含义
enterFragment被添加或绑定时所呈现动画的资源id
exitFragment被移除或解绑时所呈现动画的资源id
popEnterFragment从栈中弹出时所呈现动画的资源id
popExitFragment压入栈时所呈现动画的资源id

为了便于区分这里笔者就直接通过不同的背景表示不同的Fragment,这里我们采用平移动画切换Fragment,Java代码如下所示:

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button prevButton;
    private Button nextButton;
    private FirstFragment firstFragment;
    private SecondFragment secondFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        prevButton = (Button)findViewById(R.id.prev_button);
        nextButton = (Button)findViewById(R.id.next_button);
        prevButton.setOnClickListener(this);
        nextButton.setOnClickListener(this);
        firstFragment = new FirstFragment();
        secondFragment = new SecondFragment();
        getSupportFragmentManager().beginTransaction().add(R.id.container, firstFragment).commit();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.prev_button:
                getSupportFragmentManager().beginTransaction()
                        .setCustomAnimations(R.anim.slide_left_in, R.anim.slide_right_out)
                        .replace(R.id.container, firstFragment)
                        .commit();
                break;
            case R.id.next_button:
                getSupportFragmentManager().beginTransaction()
                        .setCustomAnimations(R.anim.slide_right_in, R.anim.slide_left_out)
                        .replace(R.id.container, secondFragment)
                        .commit();
                break;
        }
    }
}

效果图如下所示:
在这里插入图片描述
android.app.Fragment

实际上普通Fragment和v4包下的Fragment使用非常相似,但是需要注意的是v4包下的Fragment只能采用补间动画,而普通Fragment则可以采用属性动画。由于使用非常相似,这里就不再赘述了。


二、帧动画

帧动画其实也属于补间动画的一种,所以它的作用对象也是View。它按照顺序播放一组预先定义好的图片。系统提供了 AnimationDrawable 类来使用帧动画。它的实现同样有XML形式和Java代码的形式。

1. XML文件形式

首先我们需要一个XML文件来定义一个AnimationDrawable,该XML文件必须位于 res/drawable/ 文件夹下,如下所示:

// res/drawable/frame_anim.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/anim_1" android:duration="200"/>
    <item android:drawable="@drawable/anim_2" android:duration="200"/>
    <item android:drawable="@drawable/anim_3" android:duration="200"/>
    <item android:drawable="@drawable/anim_4" android:duration="200"/>

</animation-list>

接下来在 Activity 中,我们通过一个 ImageView 来展示帧动画,代码如下所示:

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

运行代码,效果图如下所示:
在这里插入图片描述
可以看到通过4张图片的逐帧播放,我们实现了帧动画的效果,接下来我们对帧动画的一些属性做简要的介绍。

1.1 animation-list标签

animation-list为一个图片集合,它的内部放置的就是动画中每一帧的图片,它的属性如下:

属性描述
oneshot动画是否播放一次后就停止,false为无限循环播放
visiable用于表示当前动画是否可见,true表示可见,false表示不可见

1.2 item标签

item标签就是帧动画当中的每一帧,它有两个属性如下表所示:

属性描述
drawable用于指定当前帧的图片资源
duration当前帧在动画当中的持续时间

在用XML文件设置好了之后,就可以将该文件设置为UI的背景,然后通过 AnimationDrawable#start 方法来开启帧动画了。接下来我们看到Java代码的实现方式。

2. Java代码形式

Java代码形式依然借助的是 AnimationDrawable 这个类,首先我们先通过下表来了解下这个类中的常用方法:

方法描述
start启动帧动画
addFrame向动画中添加帧,参数类型为Drawable,同时还要设置该帧的持续时间
stop停止帧动画
setOneshot设置动画是否播放一次后就停止,false为无限循环播放
setVisiable用于表示当前动画是否可见

借助上面的几个方法,一般情况下足够满足我们的需求了,接下来看到例子:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        AnimationDrawable animationDrawable = new AnimationDrawable();
        initDrawable(animationDrawable);
        ImageView imageView = (ImageView) findViewById(R.id.image_view);
        imageView.setImageDrawable(animationDrawable);
        animationDrawable.setOneShot(false);
        animationDrawable.start();
    }

    private void initDrawable(AnimationDrawable animationDrawable) {
        for (int i = 1; i <= 4; i++) {
            int id = getResources().getIdentifier("anim_" +i, "drawable", getPackageName());
            Drawable drawable = getResources().getDrawable(id);
            animationDrawable.addFrame(drawable, 200);
        }
    }

}

参考

《Android开发艺术探索》

  • 第7章 Android动画深入分析
    • 7.1 View动画

希望这篇文章对你有所帮助~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值