[TOC]
# 介绍
Android动画分为两大类:视图动画和属性动画,其中视图动画又分为补间动画和逐帧动画。
![](https://img.kancloud.cn/8b/70/8b707aa7ed8495215466ef6903d1ec0a_1184x300.png)
视图动画作用于View本身,而属性动画作用于任意Java对象。
## 补间动画
补间动画有四种动画效果:
![](https://img.kancloud.cn/4d/7d/4d7d400679f46690ea4f4380545824c9_600x250.png)
补间动画的原理是,我们来确定开始的视图样式和结束的视图样式,中间动画的变化过程由系统补全,来确定一个动画。
补间动画使用简单方便,可在xml文件中配置,也可在Java代码中动态设置。
缺点:
1、仅能控制View的整体效果,不能控制属性
2、只能实现移动、缩放、旋转、淡入淡出四种操作
3、只是改变View的显示效果,没有真正改变View的属性
## 逐帧动画
逐帧动画的原理是,按顺序播放一组预先定义好的图片,每一张图片即为一帧。
逐帧动画使用简单方便,可在xml文件配置,也可在Java代码中动态设置。但因使用大量图片资源以及大尺寸图片,容易引起OOM。
## 属性动画
![](https://img.kancloud.cn/c2/f0/c2f027c228ff71e1ead8ea68a1a36680_720x330.png)
属性动画的原理是,不断地对值进行操作,并将值赋值到指定对象的指定属性上,可以是任意对象的任意属性。
其中,ValueAnimator用于实现对一个值的动画变化,ObjectAnimator用于实现对一个对象的动画变化,AnimatorSet用于实现组合动画。
1、ValueAnimator使用示例:
```java
ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
anim.setDuration(300);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float currentValue = (float) animation.getAnimatedValue();
Log.d("TAG", "cuurent value is " + currentValue);
}
});
anim.start();
```
ValueAnimator最常用ofFloat和ofInt两个方法,还有一个ofObject方法,使用示例如下:
```java
Point point1 = new Point(0, 0);
Point point2 = new Point(300, 300);
ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), point1, point2);
anim.setDuration(5000);
anim.start();
public class PointEvaluator implements TypeEvaluator{
@Override
public Object evaluate(float fraction, Object startValue, Object endValue) {
Point startPoint = (Point) startValue;
Point endPoint = (Point) endValue;
float x = startPoint.getX() + fraction * (endPoint.getX() - startPoint.getX());
float y = startPoint.getY() + fraction * (endPoint.getY() - startPoint.getY());
Point point = new Point(x, y);
return point;
}
```
ofObject方法需要一个实现估值器TypeEvaluator接口的对象,来告诉动画系统,Object需要如何从初始值过渡到结束值。
2、ObjectAnimator使用示例:
```java
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);
animator.setDuration(5000);
animator.start();
```
ObjectAnimator的工作机制是去对象中寻找属性名(也就是上面例子中的alpha)对应的get和set方法。
ObjectAnimator同样拥有ofObject方法,在自定义View中,我们可以通过添加get和set方法,来实现动态修改View的对象类型的属性。比如,在自定义View中新增getColor和setColor方法,并实现一个TypeEvaluator来告诉系统如何变更Color的值。示例如下:
```java
ObjectAnimator anim = ObjectAnimator.ofObject(myAnimView, "color", new ColorEvaluator(),
"#0000FF", "#FF0000");
anim.setDuration(5000);
anim.start();
```
3、AnimatorSet的使用示例:
```java
ObjectAnimator moveIn = ObjectAnimator.ofFloat(textview, "translationX", -500f, 0f);
ObjectAnimator rotate = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f);
ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);
AnimatorSet animSet = new AnimatorSet();
animSet.play(rotate).with(fadeInOut).after(moveIn);
animSet.setDuration(5000);
animSet.start();
```
4、Animator的监听器使用示例:
```java
anim.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
});
// 同时提供AnimatorListenerAdapter实现,可以选择性重写部分方法
anim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
}
});
```
5、插值器(补间器)Interpolator的使用
补间器Interpolator用来控制动画从初始值过渡到结束值变化的速率,比如加速运动或者减速运动。补间器需要实现TimeInterpolator接口:
```java
public interface TimeInterpolator {
float getInterpolation(float input);
}
```
getInterpolation方法接收一个input参数, input随着动画的运行从0到1进行变化。返回值float其实就是我们前面ofObject方法中,实现TypeEvaluator时的fraction参数的值。
ofObject方法需要一个实现TypeEvaluator接口的对象,来告诉动画系统如何从初始值过渡到结束值。而补间器就是为了告诉TypeEvaluator fraction是如何变化的。
Animator有一个setInterpolator方法直接设置补间器:
```java
anim.setInterpolator(new AccelerateInterpolator(2f));
```
6、ViewPropertyAnimator的使用
从Android3.1开始,View类新增了animate方法,该方法会返回一个ViewPropertyAnimator对象,我们拿到这个对象后可以操作它实现各种动画效果了,示例如下:
```java
textview.animate().x(500).y(500).setDuration(5000)
.setInterpolator(new BounceInterpolator());
```
# 总结
1、Android动画分为两大类:视图动画和属性动画,其中视图动画又分为补间动画和逐帧动画。
2、视图动画作用于View本身,属性动画作用于任意Java对象。
3、补间动画的原理是,我们确定好开始的视图样式和结束的视图样式,中间过程变化由系统补全,来实现一个动画。
4、逐帧动画的原理是,按顺序播放一组预先定义好的图片,每一张图片即为一帧。
5、属性动画的原理是,不断的对值进行操作,并将值赋值到指定对象的指定属性上,可以是任意对象的任意属性。
6、补间动画仅能控制整体效果以及显示效果,不能真正改变View的属性,且操作只有那几种;逐帧动画使用大量图片,容易引起OOM;而属性动画可以真正改变View的任何属性,可控制变化速率等。
7、ValueAnimator用于实现对一个值的动画变化;ObjectAnimator用于实现对一个对象的动画变化;AnimatorSet用于实现组合动画。
8、ObjectAnimator的工作机制是寻找对象中属性名对应的get方法和set方法,并调用。
9、估值器TypeEvaluator用来告诉动画系统,Object需要如何从初始值过渡到结束值,也就是动画变化时Object需要怎样变化;插值器(补间器)Interpolator用来控制动画从初始值过渡到结束值变化的速率。
10、Android3.1开始,View类新增animate方法,返回一个ViewPropertyAnimator对象,我们可以操作这个对象来实现各种动画效果。
节选自:
[Android属性动画完全解析(上),初识属性动画的基本用法](https://blog.csdn.net/guolin_blog/article/details/43536355)
[Android属性动画完全解析(中),ValueAnimator和ObjectAnimator的高级用法](https://blog.csdn.net/guolin_blog/article/details/43816093)
[Android属性动画完全解析(下),Interpolator和ViewPropertyAnimator的用法](https://blog.csdn.net/guolin_blog/article/details/44171115)
- 导读
- Java知识
- Java基本程序设计结构
- 【基础知识】Java基础
- 【源码分析】Okio
- 【源码分析】深入理解i++和++i
- 【专题分析】JVM与GC
- 【面试清单】Java基本程序设计结构
- 对象与类
- 【基础知识】对象与类
- 【专题分析】Java类加载过程
- 【面试清单】对象与类
- 泛型
- 【基础知识】泛型
- 【面试清单】泛型
- 集合
- 【基础知识】集合
- 【源码分析】SparseArray
- 【面试清单】集合
- 多线程
- 【基础知识】多线程
- 【源码分析】ThreadPoolExecutor源码分析
- 【专题分析】volatile关键字
- 【面试清单】多线程
- Java新特性
- 【专题分析】Lambda表达式
- 【专题分析】注解
- 【面试清单】Java新特性
- Effective Java笔记
- Android知识
- Activity
- 【基础知识】Activity
- 【专题分析】运行时权限
- 【专题分析】使用Intent打开三方应用
- 【源码分析】Activity的工作过程
- 【面试清单】Activity
- 架构组件
- 【专题分析】MVC、MVP与MVVM
- 【专题分析】数据绑定
- 【面试清单】架构组件
- 界面
- 【专题分析】自定义View
- 【专题分析】ImageView的ScaleType属性
- 【专题分析】ConstraintLayout 使用
- 【专题分析】搞懂点九图
- 【专题分析】Adapter
- 【源码分析】LayoutInflater
- 【源码分析】ViewStub
- 【源码分析】View三大流程
- 【源码分析】触摸事件分发机制
- 【源码分析】按键事件分发机制
- 【源码分析】Android窗口机制
- 【面试清单】界面
- 动画和过渡
- 【基础知识】动画和过渡
- 【面试清单】动画和过渡
- 图片和图形
- 【专题分析】图片加载
- 【面试清单】图片和图形
- 后台任务
- 应用数据和文件
- 基于网络的内容
- 多线程与多进程
- 【基础知识】多线程与多进程
- 【源码分析】Handler
- 【源码分析】AsyncTask
- 【专题分析】Service
- 【源码分析】Parcelable
- 【专题分析】Binder
- 【源码分析】Messenger
- 【面试清单】多线程与多进程
- 应用优化
- 【专题分析】布局优化
- 【专题分析】绘制优化
- 【专题分析】内存优化
- 【专题分析】启动优化
- 【专题分析】电池优化
- 【专题分析】包大小优化
- 【面试清单】应用优化
- Android新特性
- 【专题分析】状态栏、ActionBar和导航栏
- 【专题分析】应用图标、通知栏适配
- 【专题分析】Android新版本重要变更
- 【专题分析】唯一标识符的最佳做法
- 开源库源码分析
- 【源码分析】BaseRecyclerViewAdapterHelper
- 【源码分析】ButterKnife
- 【源码分析】Dagger2
- 【源码分析】EventBus3(一)
- 【源码分析】EventBus3(二)
- 【源码分析】Glide
- 【源码分析】OkHttp
- 【源码分析】Retrofit
- 其他知识
- Flutter
- 原生开发与跨平台开发
- 整体归纳
- 状态及状态管理
- 零碎知识点
- 添加Flutter到现有应用
- Git知识
- Git命令
- .gitignore文件
- 设计模式
- 创建型模式
- 结构型模式
- 行为型模式
- RxJava
- 基础
- Linux知识
- 环境变量
- Linux命令
- ADB命令
- 算法
- 常见数据结构及实现
- 数组
- 排序算法
- 链表
- 二叉树
- 栈和队列
- 算法时间复杂度
- 常见算法思想
- 其他技术
- 正则表达式
- 编码格式
- HTTP与HTTPS
- 【面试清单】其他知识
- 开发归纳
- Android零碎问题
- 其他零碎问题
- 开发思路