美文网首页Android开发进阶经验分享
Android动画上篇(补间动画、帧动画)

Android动画上篇(补间动画、帧动画)

作者: luoqiang108 | 来源:发表于2018-11-03 07:47 被阅读0次

前言

  • 动画的使用是Android开发中常用的知识。种类繁多,使用复杂,往往是我们开发中的一大难点,今天我就对此来做个总结,方便今后开发使用。


    Android动画分类.png

补间动画

作用对象

补间动画的作用对象是视图控件(View),如Android的TextView、Button等等;不可作用于View组件的属性,如颜色、背景、长度等等。

原理

补间动画的原理:通过确定开始的视图样式 & 结束的视图样式,中间动画变化过程由系统补全来确定一个动画。

分类

  • 根据不同的动画效果,补间动画可以分为4类:
  1. 平移动画(Translate)
  2. 缩放动画(scale)
  3. 旋转动画(rotate)
  4. 透明度动画(alpha)
  • 不同类型的动画对应于不同的子类,具体如下图:


    补间动画子类.png

具体使用

  • 补间动画的使用方式分为两种:在XML 代码 / Java 代码里设置

前者优点:动画描述的可读性更好
后者优点:动画效果可动态创建

  • 下面我将详细平移、缩放、旋转、透明度动画的使用步骤
平移动画(Translate)
设置方法1:在XML代码中设置
  1. 在路径res/anim的文件夹里创建动画效果 .xml 文件
  • translate_animation.xml
<?xml version="1.0" encoding="utf-8"?>
<!--4种动画效果的公共属性:
duration:动画持续时间(ms),必须设置,动画才有效果
startOffset:动画延迟开始时间(ms)
fillBefore:动画播放完后,视图是否会停留在动画开始的状态,默认为true
fillAfter:动画播放完后,视图是否会停留在动画结束的状态,优先于fillBefore值,默认为false
fillEnabled:是否应用fillBefore值,对fillAfter值无影响,默认为true
repeatMode:选择重复播放动画模式,restart代表正序重放,reverse代表倒序回放,默认为restart
repeatCount:重放次数(所以动画的播放次数=重放次数+1),为infinite时无限重复
interpolator:插值器,影响动画的播放速度,属性动画时会详细讲-->
<!--平移动画特有的属性:
fromXDelta:视图在水平方向(x)移动的起始值
toXDelta:视图在水平方向(x)移动的结束值
fromYDelta:视图在竖直方向(y)移动的起始值
toYDelta:视图在竖直方向(y)移动的结束值-->
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="3000"
    android:startOffset="1000"
    android:fillBefore="true"
    android:fillAfter="false"
    android:fillEnabled="true"
    android:repeatMode="restart"
    android:repeatCount="0"
    android:interpolator="@android:anim/linear_interpolator"

    android:fromXDelta="0"
    android:toXDelta="500"
    android:fromYDelta="0"
    android:toYDelta="500" />
  1. 在Java代码中创建Animation对象并播放动画
mport android.animation.Animator;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private Button button;
    private Animator animator;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button = findViewById(R.id.btn_anim);
        button.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_anim:
                //创建动画对象并传入设置的动画效果xml文件
                Animation animation = AnimationUtils.loadAnimation(this, R.anim.translate_animation);
                //播放动画
                button.startAnimation(animation);
                break;
        }
    }
}

3 . 效果图


平移动画.gif
设置方法2:在 Java 代码中设置
@Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_anim:
                /*
                 *创建平移动画的对象:平移动画对应的Animation子类为TranslateAnimation
                 *参数分别是:
                 *   1.fromXDelta :视图在水平方向(x)移动的起始值
                 *   2.toXDelta :视图在水平方向(x)移动的结束值
                 *   3.fromYDelta :视图在竖直方向(y)移动的起始值
                 *   4.toYDelta:视图在竖直方向(y)移动的结束值
                 * */
                Animation translateAnimation = new TranslateAnimation(0, 500, 0, 500);
                //固定属性的设置都是在其属性前加“set”,如setDuration()
                translateAnimation.setDuration(3000);
                //播放动画
                button.startAnimation(translateAnimation);
                break;
        }
    }
缩放动画(Scale)
设置方法1:在XML代码中设置
<?xml version="1.0" encoding="utf-8"?>
<!--缩放动画特有的属性:
fromXScale:动画在水平方向X的起始缩放倍数;
0.0表示收缩到没有,1.0表示正常无伸缩;
值小于1.0表示收缩;值大于1.0表示放大。
toXScale:动画在水平方向X的结束缩放倍数。
fromYScale:动画开始前在竖直方向Y的起始缩放倍数。
toYScale:动画在竖直方向Y的结束缩放倍数。
pivotX:缩放轴点的x坐标。
pivotY:缩放轴点的y坐标。
轴点 = 视图缩放的中心点;
pivotX、pivotY,可取值为数字、百分比或者百分比p;
设置为数字时(如50),轴点为View的左上角的原点在x方向和y方向加上50px的点。在Java代码里面设置这个参数的对应参数是Animation.ABSOLUTE;
设置为百分比时(如50%),轴点为View的左上角的原点在x方向加上自身宽度50%和y方向加上自身高度50%的点。在Java代码里面设置这个参数的对应参数是Animation.RELATIVE_TO_SELF;
设置为百分比p时(如50%p),轴点为View的左上角的原点在x方向加上父控件宽度50%和y方向加上父控件高度50%的点。在Java代码里面设置这个参数的对应参数是Animation.RELATIVE_TO_PARENT;
两个50%表示动画从View自身中心点开始。-->
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="3000"
    android:startOffset="1000"

    android:fromXScale="0.0"
    android:toXScale="2"
    android:fromYScale="0.0"
    android:toYScale="2"
    android:pivotX="50%"
    android:pivotY="50%">
</scale>
设置方法2:在 Java 代码中设置
@Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_anim:
                /*创建缩放动画的对象 & 设置动画效果:缩放动画对应的Animation子类为RotateAnimation
                参数说明:
                1.fromX:动画在水平方向X的结束缩放倍数
                2.toX:动画在水平方向X的结束缩放倍数
                3.fromY:动画开始前在竖直方向Y的起始缩放倍数
                4.toY:动画在竖直方向Y的结束缩放倍数
                5.pivotXType:缩放轴点的x坐标的模式
                6.pivotXValue:缩放轴点x坐标的相对值
                7.pivotYType:缩放轴点的y坐标的模式
                8.pivotYValue:缩放轴点y坐标的相对值

                pivotXType = Animation.ABSOLUTE:缩放轴点的x坐标 = View左上角的原点在x方向加上pivotXValue数值的点(y方向同理)
                pivotXType = Animation.RELATIVE_TO_SELF:缩放轴点的x坐标 = View左上角的原点在x方向加上自身宽度乘上pivotXValue数值的值(y方向同理)
                pivotXType = Animation.RELATIVE_TO_PARENT:缩放轴点的x坐标 = View左上角的原点在x方向加上父控件宽度乘上pivotXValue数值的值 (y方向同理)*/
                Animation scaleAnimation = new ScaleAnimation(0, 2, 0, 2, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
                scaleAnimation.setDuration(3000);
                //播放动画
                button.startAnimation(scaleAnimation);
                break;
        }
    }
效果图
缩放动画.gif
旋转动画(Rotate)
设置方法1:在XML代码中设置
<?xml version="1.0" encoding="utf-8"?>
<!--旋转动画特有的属性:
fromDegrees:动画开始时视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
toDegrees:动画结束时视图的旋转角度(正数 = 顺时针,负数 = 逆时针)-->
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="3000"
    android:startOffset="1000"

    android:fromDegrees="0"
    android:toDegrees="270"
    android:pivotX="50%"
    android:pivotY="50%">
</rotate>
设置方法2:在 Java 代码中设置
@Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_anim:
                /*创建旋转动画的对象 & 设置动画效果:旋转动画对应的Animation子类为RotateAnimation
                部分参数说明:
                1. fromDegrees :动画开始时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)
                2. toDegrees :动画结束时 视图的旋转角度(正数 = 顺时针,负数 = 逆时针)*/
                Animation rotateAnimation = new RotateAnimation(0, 270, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
                rotateAnimation.setDuration(3000);
                //播放动画
                button.startAnimation(rotateAnimation);
                break;
        }
    }
效果图
旋转动画.gif
透明度动画(Alpha)
设置方法1:在XML代码中设置
<?xml version="1.0" encoding="utf-8"?>
<!--透明度动画特有的属性:
fromAlpha:动画开始时视图的透明度(取值范围: 0f - 1f)
toAlpha:动画结束时视图的透明度(取值范围: 0f - 1f)-->
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="3000"
    android:startOffset="1000"

    android:fromAlpha="1.0"
    android:toAlpha="0.0">
</alpha>
设置方法2:在 Java 代码中设置
@Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_anim:
                /*创建透明度动画的对象 & 设置动画效果:透明度动画对应的Animation子类为AlphaAnimation
                 参数说明:
                 1.fromAlpha:动画开始时视图的透明度(取值范围: 0f - 1f)
                 2.toAlpha:动画结束时视图的透明度(取值范围: 0f - 1f)*/
                Animation alphaAnimation = new AlphaAnimation(1f, 0f);
                alphaAnimation.setDuration(3000);
                //播放动画
                button.startAnimation(alphaAnimation);
                break;
        }
    }
效果图
透明度动画.gif
组合动画(Set)
  • 上面讲的都是单个动画效果,而实际中很多需求都需要同时使用平移、缩放、旋转和透明度4种动画,即组合动画。
  • 使用组合动画需要用到标签 < Set/>
设置方法1:在XML代码中设置
<?xml version="1.0" encoding="utf-8"?>
<!--组合动画独特的属性:
shareInterpolator:表示组合动画中的动画是否和集合共享同一个差值器,
默认为true,如果集合不指定插值器,那么子动画需要单独设置-->
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="3000"
    android:startOffset="1000"
    android:fillAfter="false"
    android:fillBefore="true"
    android:fillEnabled="true"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:repeatCount="0"
    android:repeatMode="restart"

    android:shareInterpolator="true">

    <!--设置旋转动画,语法同单个动画-->
    <rotate
        android:duration="1000"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatCount="infinite"
        android:repeatMode="restart"
        android:toDegrees="360" />

    <!--设置平移动画,语法同单个动画-->
    <!--延迟该动画播放时间-->
    <!--注意:组合动画播放时是全部动画同时开始,如果想不同动画不同时间开始就要使用
    android:startOffset属性来延迟单个动画播放时间-->
    <translate
        android:duration="10000"
        android:fromXDelta="-50%p"
        android:fromYDelta="0"
        android:startOffset="1000"
        android:toXDelta="50%p"
        android:toYDelta="0" />

    <!--设置透明度动画,语法同单个动画-->
    <alpha
        android:duration="3000"
        android:fromAlpha="1.0"
        android:startOffset="7000"
        android:toAlpha="0.0" />

    <!--设置缩放动画,语法同单个动画-->
    <scale
        android:duration="1000"
        android:fromXScale="1.0"
        android:fromYScale="1.0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:startOffset="4000"
        android:toXScale="0.5"
        android:toYScale="0.5" />
    <!--特别注意:
    1.在组合动画里scale缩放动画设置的repeatCount(重复播放)和fillBefore(播放完后,视图是否会停留在动画开始的状态)是无效的。
    2.所以如果需要重复播放或者回到原位的话需要在set标签里设置
    3.但是由于此处rotate旋转动画里已设置repeatCount为infinite,所以动画不会结束,也就看不到重播和回复原位-->
</set>
设置方法2:在 Java 代码中设置
 @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_anim:
                //组合动画设置,创建组合动画对象(设置为true)
                AnimationSet setAnimation = new AnimationSet(true);
                /*设置组合动画的属性
                特别说明以下情况:
                因为在下面的旋转动画设置了无限循环(RepeatCount = INFINITE)
                所以动画不会结束,而是无限循环
                所以组合动画的下面两行设置是无效的*/
                setAnimation.setRepeatMode(Animation.RESTART);
                setAnimation.setRepeatCount(1);//设置了循环一次,但无效
                setAnimation.setDuration(3000);
                setAnimation.setStartOffset(1000);
                AccelerateDecelerateInterpolator accelerateDecelerateInterpolator = new AccelerateDecelerateInterpolator();
                setAnimation.setInterpolator(accelerateDecelerateInterpolator);
                //setAnimation.setInterpolator(this,android.R.anim.accelerate_decelerate_interpolator);等同于上面效果
                //逐个创建子动画(方式同单个动画创建方式,此处不作过多描述)
                //子动画1:旋转动画
                Animation rotate = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
                rotate.setDuration(1000);
                rotate.setRepeatMode(Animation.RESTART);
                rotate.setRepeatCount(Animation.INFINITE);
                //子动画2:平移动画
                Animation translate = new TranslateAnimation(TranslateAnimation.RELATIVE_TO_PARENT, -0.5f,
                        TranslateAnimation.RELATIVE_TO_PARENT, 0.5f,
                        TranslateAnimation.RELATIVE_TO_SELF, 0,
                        TranslateAnimation.RELATIVE_TO_SELF, 0);
                translate.setStartOffset(1000);
                translate.setDuration(10000);
                //子动画3:透明度动画
                Animation alpha = new AlphaAnimation(1, 0);
                alpha.setDuration(3000);
                alpha.setStartOffset(7000);
                //子动画4:缩放动画
                Animation scale = new ScaleAnimation(1, 0.5f, 1, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
                scale.setDuration(1000);
                scale.setStartOffset(4000);
                //步骤4:将创建的子动画添加到组合动画里
                setAnimation.addAnimation(alpha);
                setAnimation.addAnimation(rotate);
                setAnimation.addAnimation(translate);
                setAnimation.addAnimation(scale);
                //播放动画
                button.startAnimation(setAnimation);
                break;
        }
    }
效果图 组合动画.gif

监听动画

  • Animation类通过监听动画开始 / 结束 / 重复时刻来进行一系列操作,如跳转页面等等。
  • 通过在 Java 代码里setAnimationListener()方法设置。
setAnimation.setAnimationListener(new Animation.AnimationListener() {
                    @Override
                    public void onAnimationStart(Animation animation) {

                    }
                    @Override
                    public void onAnimationEnd(Animation animation) {

                    }
                    @Override
                    public void onAnimationRepeat(Animation animation) {

                    }
                });

特殊应用场景

1. Activity 的切换效果
  • 即 Activity 启动 / 退出时的动画效果。
启动动画
Intent intent = new Intent (this,Acvtivity.class);
startActivity(intent);
overridePendingTransition(R.anim.enter_anim,R.anim.exit_anim);
// 采用overridePendingTransition(int enterAnim, int exitAnim)进行设置
// enterAnim:从Activity a跳转到Activity b,进入b时的动画效果资源ID
// exitAnim:从Activity a跳转到Activity b,离开a时的动画效果资源Id

// 特别注意
// overridePendingTransition()必须要在startActivity(intent)后被调用才能生效
退出动画
@Override
public void finish(){
    super.finish();
    
    overridePendingTransition(R.anim.enter_anim,R.anim.exit_anim);
    // 采用overridePendingTransition(int enterAnim, int exitAnim)进行设置
    // enterAnim:从Activity a跳转到Activity b,进入b时的动画效果资源ID
    // exitAnim:从Activity a跳转到Activity b,离开a时的动画效果资源Id

    // 特别注意
    // overridePendingTransition()必须要在finish()后被调用才能生效
}
  • 对于参数 enterAnim & exitAnim 的资源ID,系统有自带的效果android.R.anim.xxx,如下设置:
//淡入淡出的动画效果      
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
//从左向右滑动的效果
overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
自定义左右滑动动画切换效果
  • 左右滑动 效果是采用平移动画(Translate)
  • 先了解 Activity 的位置信息,如下图


    activity位置.png

从上图可以看出:
以屏幕底边为X轴,屏幕左边为Y轴;
当Activity在X轴 = -100%p时,刚好完全超出屏幕到左边(位置1)
当Activity在X轴 = 0%p时,刚好完全在屏幕内(位置2)
当Activity在X轴 = 100%p时,刚好完全超出屏幕到右边(位置3)

  • 下面自定义一个动画效果(out_to_left.xml):从右滑到左

从中间滑到左边,即从位置2 - 位置1

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fromXDelta="0%p"
    android:toXDelta="-100%p">
</translate>
  • in_from_right.xml

从右边滑到中间,即从位置3 - 位置2

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="500"
    android:fromXDelta="100%p"
    android:toXDelta="0%p">
</translate>
  • 在Java代码中设置效果
@Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_anim:
                Intent intent = new Intent(MainActivity.this, Main2Activity.class);
                startActivity(intent);
                //自定义从右向左滑动的效果
                overridePendingTransition(R.anim.in_from_right, R.anim.out_to_left);
                break;
        }
    }
  • 效果图


    左右滑动动画.gif
  • 此处仅列出较为简单的切换效果,如想实现更多酷炫的切换动画,请看文章
2. Fragement 的切换效果
  • 系统自带的动画切换效果
FragmentManager mFragmentManager = getSupportFragmentManager();
android.support.v4.app.FragmentTransaction fragmentTransaction = mFragmentManager
        .beginTransaction();
fragmentTransaction.setTransition(int transit);
// 通过setTransition(int transit)进行设置
// transit参数说明
// 1. FragmentTransaction.TRANSIT_NONE:无动画
// 2. FragmentTransaction.TRANSIT_FRAGMENT_OPEN:标准的打开动画效果
// 3. FragmentTransaction.TRANSIT_FRAGMENT_CLOSE:标准的关闭动画效果
// 标准动画设置好后,在Fragment添加和移除的时候都会有。
  • 自定义动画效果
 FragmentManager mFragmentManager = getSupportFragmentManager();
//采用FragmentTransavtion的setCustomAnimations()进行设置
android.support.v4.app.FragmentTransaction fragmentTransaction = mFragmentManager
        .beginTransaction();
fragmentTransaction.setCustomAnimations(
        R.anim.in_from_right,
        R.anim.out_to_left);
//自定义动画效果同Activity,此处不再过多描述
3. 视图组(ViewGroup)中子元素的出场效果
  • 视图组(ViewGroup)中子元素可以具备出场时的补间动画效果
  • 常用需求场景:为ListView的item设置出场动画
  • 使用步骤:
  1. 设置子元素的出场动画
    res/anim/listview_animation.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="3000">
    <alpha
        android:duration="1500"
        android:fromAlpha="1.0"
        android:toAlpha="0.0" />
    <translate
        android:fromXDelta="500"
        android:toXDelta="0" />
</set>
  1. 设置 视图组(ViewGroup)的动画文件
    res/ anim /anim_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<!--采用LayoutAnimation标签
delay:子元素开始动画的时间延迟(单位ms)
那么 delay = "0.5" 表示每个子元素都会延迟0.5ms才会播放动画效果;
第一个子元素延迟0.5ms播放入场效果;第二个延迟1ms,以此类推。
animationOrder:表示子元素动画的顺序
可设置属性为:
1. normal:顺序显示,即排在前面的子元素先播放入场动画;
2. reverse:倒序显示,即排在后面的子元素先播放入场动画;
3. random:随机播放入场动画。
animation:设置入场的具体动画效果
将步骤1的子元素出场动画设置到这里。-->
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
    android:animation="@anim/listview_animation"
    android:animationOrder="normal"
    android:delay="0.5">
</layoutAnimation>
  1. 为视图组(ViewGroup)指定andorid:layoutAnimation属性

方式1:在 XML 中指定

<!--layoutAnimation属性用以指定子元素的入场动画-->
    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/btn_anim"
        android:layoutAnimation="@anim/anim_layout" />

方式2:在Java代码中指定

  • 这样就不用额外设置res/ anim /anim_layout.xml该xml文件了
         ListView listView = findViewById(R.id.listView);
         String[] datas = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"};
         listView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1, datas));

         // 加载子元素的出场动画
         Animation animation = AnimationUtils.loadAnimation(this, R.anim.listview_animation);
         LayoutAnimationController controller = new LayoutAnimationController(animation);
         // 设置LayoutAnimation的属性
         controller.setDelay(0.5f);
         controller.setOrder(LayoutAnimationController.ORDER_NORMAL);
         // 为ListView设置LayoutAnimation的属性
         listView.setLayoutAnimation(controller);
  1. 效果图


    viewGroup动画.gif

帧动画

原理

  • 将动画拆分为 帧 的形式,且定义每一帧 = 每一张图片
  • 逐帧动画的本质:按序播放一组预先定义好的图片

具体使用

1. 将动画资源(即每张图片资源)放到drawable文件夹里

技巧:

  1. 找到自己需要的gif动画
  2. 用 gif分解软件(如 GifSplitter)将 gif 分解成一张张图片即可
2. 设置 & 启动动画

设置 & 启动逐帧动画有两种方式:在XML / Java代码。

  • 方式1:XML实现
  1. 在 res/anim的文件夹里创建动画效果.xml文件
<?xml version="1.0" encoding="utf-8"?>
<!--oneshot:设置是否只播放一次,默认为false-->
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="true">
    <!--item = 动画图片资源;duration = 设置一帧持续时间(ms)-->
    <item
        android:drawable="@drawable/chazuokaiguan13"
        android:duration="100"/>
    <item
        android:drawable="@drawable/chazuokaiguan12"
        android:duration="100"/>
    <item
        android:drawable="@drawable/chazuokaiguan11"
        android:duration="100"/>
    <item
        android:drawable="@drawable/chazuokaiguan10"
        android:duration="100"/>
    <item
        android:drawable="@drawable/chazuokaiguan9"
        android:duration="100"/>
    <item
        android:drawable="@drawable/chazuokaiguan8"
        android:duration="100"/>
    <item
        android:drawable="@drawable/chazuokaiguan7"
        android:duration="100"/>
    <item
        android:drawable="@drawable/chazuokaiguan6"
        android:duration="100"/>
    <item
        android:drawable="@drawable/chazuokaiguan5"
        android:duration="100"/>
    <item
        android:drawable="@drawable/chazuokaiguan4"
        android:duration="100"/>
    <item
        android:drawable="@drawable/chazuokaiguan3"
        android:duration="100"/>
    <item
        android:drawable="@drawable/chazuokaiguan2"
        android:duration="100"/>
    <item
        android:drawable="@drawable/chazuokaiguan1"
        android:duration="100"/>

</animation-list>
  1. 在Java代码中载入 & 启动动画
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private ImageView iv;
    private Button btn_start;
    private Button btn_stop;
    private AnimationDrawable animationDrawable;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        iv = findViewById(R.id.iv);
        btn_start = findViewById(R.id.btn_start);
        btn_stop = findViewById(R.id.btn_stop);
        btn_start.setOnClickListener(this);
        btn_stop.setOnClickListener(this);
        //设置动画
        iv.setImageResource(R.drawable.plug_close_anim_list);
        //获取动画对象
        animationDrawable = (AnimationDrawable) iv.getDrawable();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_start:
                //启动动画
                animationDrawable.start();
                break;
            case R.id.btn_stop:
                //暂停动画
                animationDrawable.stop();
                break;
        }
    }
}
  • 方式2:java代码实现
//直接从drawable文件夹获取动画资源(图片)
        animationDrawable = new AnimationDrawable();
        for (int i = 13; i >= 1; i--) {
            int id = getResources().getIdentifier("chazuokaiguan" + i, "drawable", getPackageName());
            Drawable drawable = getResources().getDrawable(id);
            animationDrawable.addFrame(drawable, 100);
        }
        animationDrawable.setOneShot(true);
        //设置动画对象
        iv.setImageDrawable(animationDrawable);
2. 效果图
帧动画.gif

优缺点和使用场景

  • 优点:使用简单、方便。
  • 缺点:容易引起 OOM,因为会使用大量尺寸较大的图片资源。
  • 使用场景:较为复杂的个性化动画效果;使用时一定要避免使用尺寸较大的图片,否则会引起OOM。

感谢

Android 动画:手把手教你使用 补间动画
Android 逐帧动画:关于 逐帧动画 的使用都在这里了!

相关文章

  • Android 动画锦集

    Android 动画可分为逐帧动画、补间动画、属性动画。使用传统的逐帧动画、补间动画可以实现 Android 基本...

  • Android 动画总结(1) - 概述

    Android 动画总结(2) - 帧动画Android 动画总结(3) - 补间动画Android 动画总结(4...

  • Android中的动画实践之属性动画(一 )

    接着上篇Android中的动画(XML方式)实践(逐帧动画与补间动画)来学习下属性动画。 我们知道属性...

  • 动画

    Android中的动画主要分为补间动画、帧动画和属性动画。 1.补间动画与帧动画都是canvas对matrix的操...

  • Android 动画

    【Android 动画】 动画分类补间动画(Tween动画)帧动画(Frame 动画)属性动画(Property ...

  • Android动画机制

    Android动画机制 帧动画 补间动画 属性动画 过渡动画未完待续

  • Android动画

    Android动画分类: 视图动画:补间动画、逐帧动画 属性动画 视图动画 补间动画 可以在xml中定义动画,然后...

  • Android 动画

    Android 动画分类: 传统动画 帧间动画 补间动画 属性动画ObjectAnimator 和 ValueAn...

  • Android 资源简介(五) AnimationDrawabl

    AnimationDrawable 代表动画资源。Android 既支持逐帧动画,也支持补间动画。 定义补间动画的...

  • Android动画

    Android动画 动画类型 视图动画(View Animatio)补间动画(Tween Animation)逐帧...

网友评论

    本文标题:Android动画上篇(补间动画、帧动画)

    本文链接:https://www.haomeiwen.com/subject/yobazftx.html