Android动画-全面归纳解析
简介
Android中,动画整体来说可以分为三大类,分别为:帧动画(Frame Animation),补间动画(Tween Animation)和属性动画(Property Animation),下面内容将会对这三种动画做详细讲解。
1)帧动画(Frame Animation)
帧动画,它是通过顺序播放一系列的图像从而产生动画的效果,类似于gif图的效果。Android中给我们提供AnimationDrawable类来使用帧动画,下面我们使用帧动画来实现如下加载页面。
首先,我们需要准备好这一系列图片:
然后,在drawable文件加下创建view_loading.xml文件:
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/icon_loading_1" android:duration="200"/>
<item android:drawable="@drawable/icon_loading_2" android:duration="200"/>
<item android:drawable="@drawable/icon_loading_3" android:duration="200"/>
<item android:drawable="@drawable/icon_loading_4" android:duration="200"/>
<item android:drawable="@drawable/icon_loading_5" android:duration="200"/>
<item android:drawable="@drawable/icon_loading_6" android:duration="200"/>
<item android:drawable="@drawable/icon_loading_7" android:duration="200"/>
<item android:drawable="@drawable/icon_loading_8" android:duration="200"/>
<item android:drawable="@drawable/icon_loading_9" android:duration="200"/>
<item android:drawable="@drawable/icon_loading_10" android:duration="200"/>
<item android:drawable="@drawable/icon_loading_11" android:duration="200"/>
<item android:drawable="@drawable/icon_loading_12" android:duration="200"/>
<item android:drawable="@drawable/icon_loading_13" android:duration="200"/>
</animation-list>
android:duration 表示展示该图片的时间长度
最后,在activity中添加如下代码:
private void initView(){
ivLoading = (ImageView) findViewById(R.id.iv_loading);
AnimationDrawable animationDrawable = (AnimationDrawable) getResources().getDrawable(R.drawable.view_loading);
ivLoading.setBackground(animationDrawable);
animationDrawable.start();
}
即完成上图效果,是不是十分简单。
总结:
通过上面的代码,我们可以发现,实现帧动画非常简单,首先通过 animation-list标签将多张有序的图片顺序摆放,其次通过AnimationDrawable的start函数执行,最后一个事先约定好的动画就呈现了。
那么帧动画有什么优缺点呢?
优点:
1.代码简单,可实现由一系列图片构成的不规则动画;
缺点:
1、可能涉及到大量的图片,消耗内存,图片过多可能导致OOM;
2、只能作用在某一个View上。
2)补间动画(Tween Animation)
补间动画,它主要是对View做一些简单的动画操作,例如透明渐变、位置移动、旋转及拉伸等操作。
下面首先颜色下透明渐变的实现过程,效果图如下:
如何实现该渐变过程?
首先,在res目录下创建anim文件夹,在anim文件夹下创建xml文件,具体如下:
具体内容为:
<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:fillAfter="true"
android:fromAlpha="1.0"
android:toAlpha="0.1" />
然后,在activity中添加相关代码:
private void initView(){
imageView = (ImageView) findViewById(R.id.iv_1);
Animation anim = AnimationUtils.loadAnimation(this, R.anim.tween_animation_alpha);
imageView.startAnimation(anim);
}
如上,即可完成渐变效果。
补间动画,还有其他几种效果,具体实现和渐变效果实现类似,此处不在展示,可以参考补间动画详解
总结
补间动画,主要是针对View做一些简单的操作,例如透明度、位置移动、旋转和拉伸等,同时我们可以使用set来对这几种操作集合起来做一些比较稍微炫酷的效果。
优点
相比帧动画,它少了图片的加载,可以一定程度减少ANR和OOM的产生,节省系统资源。
缺点
它仍然只能对一个View做相关的动画效果,不能改变View的属性,例如移动后的View是不能点击的,即点击事件无法与动画同时兼顾。
应用场景:Activity的切换效果、fragment的切换效果及dialog的进入退出效果等。
3)属性动画(Property Animation)
属性动画,它是在android3.0(API 11)后才提供的一种动画模式,弥补了补间动画的一些缺陷,例如按钮的点击事件。属性动画它作用的对象不再局限与View了,可以是任意一个对象,也可以自定义各种动画效果。
属性动画主要有两个重要的类,分别为ValueAnimator和ObjectAnimator。
- ValueAnimator类
ValueAnimator是属性动画机制中最核心的一个类,其运行机制是通过不断地修改对象的值来实现动画。使用过程中我们只需要将初始值和结束值提供给ValueAnimator ,并且告诉它动画所需运行的时长,那么ValueAnimator 就会自动帮我们完成从初始值平滑地过渡到结束值这样的效果。除此之外ValueAnimator 还负责管理动画的播放次数、播放模式、以及对动画设置监听器等。
下面我们具体来看一个实例:
xml文件
<Button
android:id="@+id/btn_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="按钮一"/>
activity.java
private Button btn01;
private void initView(){
btn01 = (Button) findViewById(R.id.btn_1);
btn01.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
btn1Animator();
}
});
}
// 启动动画
private void btn1Animator() {
// 步骤1:设置属性数值的初始值 & 结束值
// 初始值 = 100
// 结束值 = 500
// ValueAnimator.ofInt()内置了整型估值器,直接采用默认的.不需要设置
ValueAnimator valueAnimator = ValueAnimator.ofInt(100, 500);
// 步骤2:设置动画的播放各种属性
// 设置动画运行时长:2s
valueAnimator.setDuration(2000);
// 步骤3:将属性数值手动赋值给对象的属性:此处是将 值 赋给 按钮的宽度
// 设置更新监听器:即数值每次变化更新都会调用该方法
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animator) {
int currentValue = (Integer) animator.getAnimatedValue();
// 获得每次变化后的属性值
// 输出每次变化后的属性值进行查看
Log.i("lvjie", "currentValue="+currentValue);
// 每次值变化时,将值手动赋值给对象的属性
// 即将每次变化后的值 赋 给按钮的宽度,这样就实现了按钮宽度属性的动态变化
btn01.getLayoutParams().width = currentValue;
// 步骤4:刷新视图,即重新绘制,从而实现动画效果
btn01.requestLayout();
}
});
// 启动动画
valueAnimator.start();
}
运行结果如下:
我们不仅可以通过代码来实现动画,同时我们也可以通过xml文件来实现动画。需要注意的是 属性动画的xml文件必须是在res/animator文件夹下。
下面看看 value_animation.xml文件的具体实现:
<?xml version="1.0" encoding="utf-8"?>
<animator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="100"
android:valueTo="500"
android:valueType="intType"
android:duration="3000"
android:repeatCount = "1"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
>
</animator>
然后activity.java中代码如下:
private void btn2Animator() {
// 载入XML动画
ValueAnimator animator = (ValueAnimator) AnimatorInflater.loadAnimator(this, R.animator.value_animation);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int currentValue = (Integer) animation.getAnimatedValue();
btn02.getLayoutParams().width = currentValue;
btn02.requestLayout();
}
});
// 启动动画
animator.start();
}
最终效果和代码实现一模一样。
-
ObjectAnimator类
ObjectAnimator继承ValueAnimator类,因此具备ValueAnimator的所有特性,与ValueAnimator不同的是ObjectAnimator可以自动给对象的属性进行赋值从而实现动画,ValueAnimator需要在监听事件中手动对对象进行赋值,下面看看ObjectAnimator最简单用法。
实现方式一:Java代码实现
private void btn3Animator() {
// 表示的是:
// 动画作用对象是mButton
// 动画作用的对象的属性是X轴缩放
// 动画效果是:放大到2倍,再缩小到初始大小
ObjectAnimator animator = ObjectAnimator.ofFloat(btn03, "scaleX", 1f, 2f, 1f);
animator.setDuration(3000);
animator.start();
}
实现方式二:通过xml实现
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="1"
android:valueTo="2"
android:valueType="floatType"
android:duration="3000"
android:propertyName="scaleX">
</objectAnimator >
private void btn4Animator() {
// 载入XML动画
ObjectAnimator animator = (ObjectAnimator) AnimatorInflater.loadAnimator(this, R.animator.object_animation);
animator.setTarget(btn04);
// 启动动画
animator.start();
}
两种实现的效果一样,xml的实现方式仅仅扩大,没有恢复效果。
总结
在使用过程中,我们使用ObjectAnimator比重相对较大,ObjectAnimator内部封装了很多其他实用的方法,便于快速开发实现动画效果。
参考文献
https://www.jianshu.com/p/733532041f46
https://mp.weixin.qq.com/s/vh8Updq6hIcwLSxQP3gSlQ
上一篇: Java京东面试题之为什么HashMap线程不安全
下一篇: Android 动画