一.简介

1.定义

Android实现动画效果中的一个辅助接口。

2.作用

设置 属性值 从初始值过渡到结束值 的变化规律,实现非线性运动的动画效果。

二.使用

1.Xml方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"

// 通过资源ID设置插值器
android:interpolator="@android:anim/overshoot_interpolator"

android:fromXScale="0.0"
android:fromYScale="0.0"
android:toXScale="2"
android:toYScale="2"
android:pivotX="50%"
android:pivotY="50%"

android:duration="3000"
/>

2.Java代码

1
animation.setInterpolator(overshootInterpolator);

三.系统内置插值器

1.类型

系统默认的插值器是AccelerateDecelerateInterpolator,即先加速后减速。

2.效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

//平移动画
final TranslateAnimation translateAnimation = new TranslateAnimation(0, 500, 0, 0);
translateAnimation.setDuration(2000);

findViewById(R.id.accelerate).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
translateAnimation.setInterpolator(new AccelerateInterpolator());

v.startAnimation(translateAnimation);
}
});

findViewById(R.id.overshoot).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
translateAnimation.setInterpolator(new OvershootInterpolator());

v.startAnimation(translateAnimation);
}
});

findViewById(R.id.ac_de_celerate).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
translateAnimation.setInterpolator(new AccelerateDecelerateInterpolator());

v.startAnimation(translateAnimation);
}
});

findViewById(R.id.anticipate).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
translateAnimation.setInterpolator(new AnticipateInterpolator());

v.startAnimation(translateAnimation);
}
});

findViewById(R.id.anti_overshoot).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
translateAnimation.setInterpolator(new AnticipateOvershootInterpolator());

v.startAnimation(translateAnimation);
}
});

findViewById(R.id.bounce).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
translateAnimation.setInterpolator(new BounceInterpolator());

v.startAnimation(translateAnimation);
}
});

findViewById(R.id.cycle).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
translateAnimation.setInterpolator(new CycleInterpolator(1.5f));

v.startAnimation(translateAnimation);
}
});

findViewById(R.id.decelerate).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
translateAnimation.setInterpolator(new DecelerateInterpolator());

v.startAnimation(translateAnimation);
}
});

findViewById(R.id.linear).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
translateAnimation.setInterpolator(new LinearInterpolator());

v.startAnimation(translateAnimation);
}
});
}
}

四.自定义插值器

1.本质

根据动画的进度(0%-100%)计算出当前属性值改变的百分比

2.实现方式

自定义插值器需要实现 Interpolator / TimeInterpolator接口 & 重写getInterpolation()

  • 补间动画 实现 Interpolator接口;属性动画实现TimeInterpolator接口
  • TimeInterpolator接口是属性动画中新增的,用于兼容Interpolator接口,这使得所有过去的Interpolator实现类都可以直接在属性动画使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Interpolator接口
public interface Interpolator {

// 内部只有一个方法
float getInterpolation(float input) {
// 参数说明
// input值值变化范围是0-1,且随着动画进度(0% - 100% )均匀变化
// 即动画开始时,input值 = 0;动画结束时input = 1
// 而中间的值则是随着动画的进度(0% - 100%)在0到1之间均匀增加
...
// 插值器的计算逻辑

return xxx;
// 返回的值就是用于估值器继续计算的fraction值,下面会详细说明
}

// TimeInterpolator接口
// 同上
public interface TimeInterpolator {

float getInterpolation(float input);

}

3.系统的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 匀速差值器:LinearInterpolator
@HasNativeInterpolator
public class LinearInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {
// 仅贴出关键代码
...
public float getInterpolation(float input) {
return input;
// 没有对input值进行任何逻辑处理,直接返回
// 即input值 = fraction值
// 因为input值是匀速增加的,因此fraction值也是匀速增加的,所以动画的运动情况也是匀速的,所以是匀速插值器
}


// 先加速再减速 差值器:AccelerateDecelerateInterpolator
@HasNativeInterpolator
public class AccelerateDecelerateInterpolator implements Interpolator, NativeInterpolatorFactory {
// 仅贴出关键代码
...
public float getInterpolation(float input) {
return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
// input的运算逻辑如下:
// 使用了余弦函数,因input的取值范围是0到1,那么cos函数中的取值范围就是π到2π。
// 而cos(π)的结果是-1,cos(2π)的结果是1
// 所以该值除以2加上0.5后,getInterpolation()方法最终返回的结果值还是在0到1之间。只不过经过了余弦运算之后,最终的结果不再是匀速增加的了,而是经历了一个先加速后减速的过程
// 所以最终,fraction值 = 运算后的值 = 先加速后减速
// 所以该差值器是先加速再减速的
}
}

4.自定义 Interpolator

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class DecelerateAccelerateInterpolator implements Interpolator {

@Override
public float getInterpolation(float input) {
float result;
if (input <= 0.5) {
result = (float) (Math.sin(Math.PI * input)) / 2;
// 使用正弦函数来实现先减速后加速的功能,逻辑如下:
// 因为正弦函数初始弧度变化值非常大,刚好和余弦函数是相反的
// 随着弧度的增加,正弦函数的变化值也会逐渐变小,这样也就实现了减速的效果。
// 当弧度大于π/2之后,整个过程相反了过来,现在正弦函数的弧度变化值非常小,渐渐随着弧度继续增加,变化值越来越大,弧度到π时结束,这样从0过度到π,也就实现了先减速后加速的效果
} else {
result = (float) (2 - Math.sin(Math.PI * input)) / 2;
}
return result;
// 返回的result值 = 随着动画进度呈先减速后加速的变化趋势
}
}