本篇博客来看一下Android中的逐帧动画和补间动画。


一、逐帧动画
逐帧动画也叫Drawable Animation。
在Android中实现逐帧动画,就是由设计师给出一系列状态不断变化的图片,
开发者可以指定动画中每一帧对应的图片和持续的时间,然后在合适的时候播发动画。

最常用定义逐帧动画的方式是:
在res/drawable目录下,放置动画对应的图片,并定义animation.xml文件。
animation.xml的定义类似于:

<?xml version="1.0" encoding="utf-8" ?>
<!--oneshot表示是否重复播放动画, true表示只播放一次, false表示重复播放 -->
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"android:oneshot="true"><!--drawable指定图片, duration表示图像的持续时间--><item
        android:drawable= "@drawable/p_1"android:duration="1200"/><item
        android:drawable= "@drawable/p_2"android:duration="1200"/><item
        android:drawable= "@drawable/p_3"android:duration="1200"/>
</animation-list>

负责播放动画的View,需要在xml中配置src属性为animation.xml,例如:

<ImageView
    android:id="@+id/test_view"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/animation" />

然后就可以在代码中,启动动画了:

ImageView imageView = findViewById(R.id.test_view);//获取AnimationDrawable
AnimationDrawable drawable = (AnimationDrawable)imageView.getDrawable();//调用start接口开始播放
//AnimationDrawable还有其它接口,例如停止、增加帧等
drawable.start();

如果不定义animation.xml文件,也可以仅通过代码实现逐帧动画:

        //在Activity中直接getDrawable,需要API >= 21if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {AnimationDrawable animationDrawable = new AnimationDrawable();int[] ids = new int[] {R.drawable.p_1, R.drawable.p_2, R.drawable.p_3};for (int id : ids) {Drawable tmp = getDrawable(id);if (tmp != null) {//利用addFrame接口, 增加帧animationDrawable.addFrame(tmp, 1200);}}animationDrawable.setOneShot(true);ImageView testView = findViewById(R.id.another_test_view);//设置animationDrawabletestView.setBackground(animationDrawable);animationDrawable.start();}}

二、补间动画
补间动画是指开发者无需定义动画过程中的每一帧,
只需要定义动画的开发和结束这两个关键帧,并指定动画变化的时间和方式等,
然后交由Android系统进行计算,通过在两个关键帧之间插入渐变值来实现平滑过渡,
以实现对View的内容进行一系列的图形变换的动画效果。

补间动画主要包括四种基本效果:
透明度变化Alpha、大小变化Scale、位移变化Translate及旋转变化Rotate,
这四种效果可以动态组合,从而实现复杂灵活的动画。

Android中使用Animation来抽象动画类,对应上述四种补间动画的实现分别为:
AlphaAnimation:
改变透明度的动画,创建动画时需要指定动画开始和结束的透明度,
以及动画持续的时间,透明度取值范围是0到1。

ScaleAnimation:
缩放大小的动画,创建动画时需要指定动画开始和结束时在X轴和Y轴的缩放比,以及动画的持续时间;
同时由于缩放时以不同的点作为中心会产生不同的效果,因此也需要通过pivotX和pivotY指定缩放中心的坐标。

TranslateAnimation:
改变位置的动画,创建动画时需要指定动画开始和结束时的X、Y坐标,以及动画的持续时间。

RotateAnimation:
旋转动画,创建动画时需要指定动画开始和结束时的旋转角度,以及动画的持续时间;
同时由于旋转时以不同的点作为中心会产生不同的效果,因此也需要通过pivotX和pivotY指定旋转中心的坐标。

2.1、插值器Interpolator
在分析进一步补间动画前,我们有必要先了解一下插值器Interpolator。

Android系统会在补间动画的开始和结束帧之间插入渐变值,它的依据便是Interpolator。
Interpolator会根据类型,选择不同的算法,计算出在补间动画期间所需要动态插入帧的密度和位置。

简单来讲,Interpolator负责控制动画的变化速度,
使得动画效果能够以匀速、加速、减速、抛物线等多种速度进行变化。

Android中的Interpolator类是一个空接口,继承TimeInterpolator:

/*** A time interpolator defines the rate of change of an animation. This allows animations* to have non-linear motion, such as acceleration and deceleration.*/
public interface TimeInterpolator {/*** Maps a value representing the elapsed fraction of an animation to a value that represents* the interpolated fraction. This interpolated value is then multiplied by the change in* value of an animation to derive the animated value at the current elapsed animation time.** @param input A value between 0 and 1.0 indicating our current point*        in the animation where 0 represents the start and 1.0 represents*        the end* @return The interpolation value. This value can be more than 1.0 for*         interpolators which overshoot their targets, or less than 0 for*         interpolators that undershoot their targets.*/float getInterpolation(float input);
}

通过注释容易了解到,TimeInterpolator时间插值器允许动画进行非线性变换,如加速、减速变化等。
TimeInterpolator只有一个函数getInterpolation,
其输入参数表示当前帧在整个动画过程中对应的比例,取值范围在0~1之间;
输出表示输入值对应的映射值。

Android已经定义了一些Interpolator的实现类,
例如:AccelerateInterpolator、AccelerateDecelerateInterpolator等。

我们以AccelerateInterpolator的getInterpolation函数为例,看看具体的实现:

    //AccelerateInterpolator的映射值为输入的平方或指数结果//那么显然输入的值越大,输出就越大//且随着输入的增大,输出增大速率越来越大//这就是会导致一种加速的效果public float getInterpolation(float input) {if (mFactor == 1.0f) {return input * input;} else {return (float)Math.pow(input, mDoubleFactor);}}

2.2、实现示例
了解完Interpolator后,我们来看看各种补间动画如何实现。

2.2.1、AlphaAnimation的实现
用XML定义AlphaAnimation时,需要在res/anim目录下建立对应的xml文件,其内容类似于:

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"android:duration="1200"android:fillAfter="true"     //动画结束之后是否保持动画的最终状态;    true, 表示保持动画的最终状态 android:fillBefore="false"   //动画结束之后是否恢复到动画开始前的状态; true, 表示恢复到动画开始前的状态 android:fromAlpha="0.0"      //初始透明度android:interpolator="@android:anim/accelerate_interpolator"  //指定插值器android:toAlpha="1.0"        //最终的透明度android:repeatCount="-1"     //指定动画重复播放的次数; 如果需要无限循环播放, 填写一个小于0的数android:repeatMode="restart" //动画重复的Mode, 有reverse和restart两种android:startOffset="200"/>  //动画播放延迟时长

在代码中使用XML定义动画的方式类似于:

AlphaAnimation alphaAnimation = (AlphaAnimation) AnimationUtils.loadAnimation(this, R.anim.alpha_animation);
ImageView imageView = findViewById(R.id.test_view);
imageView.startAnimation(alphaAnimation);

仅用Java来实现AlphaAnimation时,对应代码类似于:

//直接创建AlphaAnimation对象
//xml中定义的属性都有对应的接口可以调用,此处仅举例一下
AlphaAnimation alphaAnimation = new AlphaAnimation(0.0f, 1.0f);
alphaAnimation.setDuration(1000);
alphaAnimation.setInterpolator(new AccelerateInterpolator(2));
alphaAnimation.setRepeatCount(2);ImageView imageView = findViewById(R.id.test_view);
imageView.startAnimation(alphaAnimation);

2.2.2、ScaleAnimation的实现
用XML定义ScaleAnimation时,需要在res/anim目录下建立对应的xml文件,其内容类似于:

<?xml version="1.0" encoding="utf-8"?><scale xmlns:android="http://schemas.android.com/apk/res/android"android:duration="2000"android:fromXScale="0.2"android:fromYScale="0.2"android:pivotX="50%"android:pivotY="50%"android:toXScale="1.5"android:toYScale="1.5"android:repeatCount="-1"/>

在代码中使用XML定义动画的方式类似于:

ImageView imageView = findViewById(R.id.test_view);
ScaleAnimation scaleAnimation = (ScaleAnimation)AnimationUtils.loadAnimation(this, R.anim.scale_animation);
imageView.startAnimation(scaleAnimation);

仅用Java来实现ScaleAnimation时,对应代码类似于:

ImageView imageView = findViewById(R.id.test_view);
ScaleAnimation scaleAnimation = new ScaleAnimation(1.0f, 4.0f, 1.0f, 4.0f);
scaleAnimation.setDuration(2000);
imageView.startAnimation(scaleAnimation);

ScaleAnimation构造函数的参数较多,具体含义可以参考对应的doc文档。

2.2.3、TranslateAnimation的实现
用XML定义ScaleAnimation时,需要在res/anim目录下建立对应的xml文件,其内容类似于:

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"android:duration="2000"android:fromXDelta="0"android:fromYDelta="0"android:toXDelta="0"android:toYDelta="100" />

在代码中使用XML定义动画的方式类似于:

ImageView imageView = findViewById(R.id.test_view);
TranslateAnimation animation = (TranslateAnimation)AnimationUtils.loadAnimation(this, R.anim.translate_animation);
imageView.startAnimation(animation);

仅用Java来实现TranslateAnimation时,对应代码类似于:

ImageView imageView = findViewById(R.id.test_view);
TranslateAnimation animation = new TranslateAnimation(0f, 100f, 0f, 100f);
animation.setDuration(3000);
animation.setFillAfter(true);
imageView.startAnimation(animation);

TranslateAnimation构造函数的参数较多,具体含义可以参考对应的doc文档。

2.2.4、RotateAnimation的实现
用XML定义ScaleAnimation时,需要在res/anim目录下建立对应的xml文件,其内容类似于:

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

在代码中使用XML定义动画的方式类似于:

ImageView imageView = findViewById(R.id.test_view);
RotateAnimation animation = (RotateAnimation) AnimationUtils.loadAnimation(this, R.anim.rotate_animation);
imageView.startAnimation(animation);

仅用Java来实现TranslateAnimation时,对应代码类似于:

ImageView imageView = findViewById(R.id.test_view);
RotateAnimation animation = new RotateAnimation(0, -720, 0.5f, 0.5f);
animation.setDuration(1000);
imageView.startAnimation(animation);

2.3、自定义补间动画
在实际的项目中,上述默认的基本动画可能无法满足需求,
此时就可能需要自定义补间动画了。
具体的做法就是集成Animation类,然后重写其中的applyTransformation方法:

protected void applyTransformation(float interpolatedTime, Transformation t) {
}

其中:
interpolatedTime代表了动画的时间进行比。
不管动画实际的持续时间如何,当动画播放时,该参数总是自动从0变化到1。
Transformation代表了补间动画在不同时刻对图形或组件的变形程度,
该对象里封装了一个Matrix对象。
Transformation实际上就是通过对Matrix对象进行旋转、位置、倾斜等,
实现对图片或者视图进行相应的变换。

从applyTransformation的参数可以看出,实现自定义补间动画的重点就在于:
重写applyTransformation方法时,根据interpolatedTime,动态的计算动画对图形的变形程度。

我们来看一个具体的例子:

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ImageView imageView = findViewById(R.id.test_view);DemoAnimation animation = new DemoAnimation(150, 150, 5000);imageView.startAnimation(animation);}//自定义的补间动画private class DemoAnimation extends Animation {private float mCenterX;private float mCenterY;private int mDuration;//这里使用的是:android.graphics.Camera类//用于空间变换的工具private Camera mCamera = new Camera();public DemoAnimation(float x, float y, int duration) {mCenterX = x;mCenterY = y;mDuration = duration;}@Overridepublic void initialize(int width, int height, int parentWidth, int parentHeight) {super.initialize(width, height, parentWidth, parentHeight);setDuration(mDuration);setFillAfter(true);setInterpolator(new LinearInterpolator());}@Overrideprotected void applyTransformation(float interpolatedTime, Transformation t) {super.applyTransformation(interpolatedTime, t);mCamera.save();//根据interpolatedTime来控制x、y和z轴上的偏移mCamera.translate(100.0f - 100.0f * interpolatedTime,150.0f * interpolatedTime - 150, 80.0f - 80.0f * interpolatedTime);//设置x和y轴的旋转角度mCamera.rotateX(360 * interpolatedTime);mCamera.rotateY(360 * interpolatedTime);//获取Transformation中的matrixMatrix matrix = t.getMatrix();//将camera计算出的数据拷贝到matrix中,//即应用到Transformation中mCamera.getMatrix(matrix);//在旋转前、后移动图片//实际上就是更改图片的旋转中心matrix.preTranslate(-mCenterX, -mCenterY);matrix.postTranslate(mCenterX, mCenterY);mCamera.restore();}}
}

总结
至此,我们已经基本了解了逐帧动画和补间动画的使用方式。
其中,逐帧动画的使用最为简单;
补间动画既可以利用XML定义,也可以仅用Java代码实现。
对于基本的补间动画,主要是要选择合适的插值器以及配置参数;
对于自定义的补间动画,则可以利用Camera类来简化Matrix类的计算。

Android逐帧动画和补间动画相关推荐

  1. android属性动画替换逐帧动画,Android 动画:逐帧动画,补间动画和属性动画

    1.三种动画的介绍 现在 Android 常用的动画有三种: 逐帧动画,补间动画和属性动画: FrameAnimation(逐帧动画):将多张图片组合起来进行播放,很多 App 的加载动画是采用这种方 ...

  2. Android之帧动画与补间动画的使用

    前言 在日常开发中,我们有时候需要一些好看的动画效果,这时可以充分利用Android提供的这几种动画来实现, Android提供了3种类型的动画: 补间动画:补间动画可以应用于View,让你可以定义一 ...

  3. 逐帧动画和补间动画的使用场景(二)

    2019独角兽企业重金招聘Python工程师标准>>> 逐帧动画和补间动画的使用场景(二) 上一节我们详细的介绍了补间动画和逐帧动画的基本使用,如果你对这还不熟悉的请看这篇文章: h ...

  4. Android动画(帧动画、补间动画、属性动画)讲解

    Android动画(帧动画.补间动画.属性动画)讲解 首先我们来看看啥是帧动画.补间动画.属性动画. 介绍: 帧动画:是一种常见的动画形式(Frame By Frame),其原理是在"连续的 ...

  5. Android动画之帧动画和补间动画

    Android系统提供三种动画:帧动画.补间动画和属性动画.这里先分析总结帧动画和补间动画. FrameAnimation 帧动画,通俗来说就是按照图片动作顺序依次播放来形成动画,创建帧动画可以用 x ...

  6. Android帧动画特点,Android帧动画和补间动画看这篇足够了

    原标题:Android帧动画和补间动画看这篇足够了 距离活动开始还有两天,重庆的开发者们赶快报名行动起来吧! 写在前面 为了使用户的交互更加流畅自然,动画也就成为了一个应用中必不可少的元素之一.在 A ...

  7. android 帧动画张数限制,Android帧动画和补间动画看这篇足够了

    原标题:Android帧动画和补间动画看这篇足够了 写在前面 为了使用户的交互更加流畅自然,动画也就成为了一个应用中必不可少的元素之一.在 Android 中常用的动画分类无外乎三种,最早的帧动画.补 ...

  8. Android帧动画和补间动画

    目录 1.帧动画 (帧动画的资源文件,放在drawable文件夹下) 1.创建一个项目 2.导入资源, 将图片资源放入 mipmap 文件夹下 3.编写资源文件 在drawable文件夹创建 4.在x ...

  9. Android 三种动画 (帧动画 、补间动画、属性动画)

    1.帧动画 帧动画是依次展示n张静态图片,造成动画的错觉,类似看视频一样. 使用方式 在drawable目录下定义XML文件,根节点为animation-list,然后放入定义更好的图片 onesho ...

最新文章

  1. PHP的静态变量介绍
  2. WOJ 1313 - K尾相等数
  3. Asp.net下web.config或是bin中的dll有变更后,重启的问题
  4. 基于xp系统搭建android开发环境
  5. jdk1.8新特性(五)——Stream
  6. Tomcat 配置Https
  7. 史上最简单JS复制功能,兼容安卓ios!
  8. python字符串编码判断
  9. mysql——解压版安装详解
  10. CentOS7 MongoDB安裝
  11. 基于Flask+Echarts+爬虫的疫情监控系统
  12. CentOS6u9 网卡HWADDR和UUID信息重新生成和获取
  13. 乱弹集锦:火柴棍艺术大神
  14. OC不可变字符串和可变字符串(1)
  15. C++图像处理函数及程序(一)
  16. 电子设计竞赛学习msp430单片机(msp430g2553,msp430f5529,tmec123G)
  17. 关键路径例题图表_详解关键路径法,这可能是你能找到的最详尽的了
  18. 院士王坚:进入空气稀薄地带
  19. 百度搜索限定时间_几个方法教你用好手中的搜索,提高搜索效率和质量
  20. 色带(8种颜色)选择器

热门文章

  1. 浅谈计算机网络故障诊断排查与维护论文,浅析计算机网络故障诊断
  2. 联创自助打印驱动程序 v1.0官方版
  3. YzmCMS轻爽极简风格Eric模版源码
  4. springboot 整合 camunda,访问 web 管理界面报错
  5. bistu新生-1005
  6. windows系统通过命令提示符(CMD)对LSP进行修复
  7. 百度地图计算两坐标点之间距离计算
  8. android build.ninja,Android中的Ninja简介
  9. 联想拯救者Y9000-ubuntu-无线网卡无效
  10. 互联网企业基本生命线