一.原理

实现动画的原理:通过不断控制 值 的变化,再不断 手动 赋给对象的属性,从而实现动画效果。如下图:

二.整型:ValueAnimator.ofInt()

1.作用

将初始值 以整型数值的形式 过渡到结束值,即估值器是整型估值器 - IntEvaluator

1
public static ValueAnimator ofInt(int... values)

2.Java代码

① 相关的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public static ValueAnimator ofInt(int... values)   
//创建动画实例 以及 将传入的多个Int参数进行平滑过渡
//ValueAnimator.ofInt()内置了整型估值器,直接采用默认的.不需要设置,即默认设置了如何从初始值 过渡到 结束值

public ValueAnimator setDuration(long duration)
//设置动画时间

public void setRepeatCount(int value)
//设置动画重复次数

public void setStartDelay(long startDelay)
//设置动画延迟时间

public void setRepeatMode(@RepeatMode int value)
//设置动画重复模式

public void addUpdateListener(AnimatorUpdateListener listener)
public static interface AnimatorUpdateListener {
void onAnimationUpdate(ValueAnimator animation);
}
public Object getAnimatedValue()
//ValueAnimator需要将改变的值手动赋值给对象的属性值
//值每次改变、变化一次,onAnimationUpdate方法就会被调用一次
//animation的getAnimatedValue()方法用来获取当前的值

② 实战小例子以及运行效果

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
public class MainActivity extends AppCompatActivity {

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

//找到要处理的控件
final View view = findViewById(R.id.btn_animation);

view.post(new Runnable() {
@Override
public void run() {
//创建ValueAnimator动画 设置值的变化范围
final ValueAnimator valueAnimator = ValueAnimator.ofInt(view.getWidth(), 500);

//动画持续的时间
valueAnimator.setDuration(1000);

//动画的重复次数
valueAnimator.setRepeatCount(1);

//动画的延迟时间
valueAnimator.setStartDelay(1000);

//动画的重复模式
valueAnimator.setRepeatMode(ValueAnimator.RESTART);

//设置更新监听器,数值每次变化更新都会调用该方法
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//获得当前应该设置的值
int currentValue = (int) animation.getAnimatedValue();

//将属性数值手动赋值给对象的属性(重新设置参数)
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
layoutParams.width = currentValue;
view.setLayoutParams(layoutParams);
}
});

//开启动画
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
valueAnimator.start();
}
});
}
});
}
}

3.Xml方式

  • 系统默认不会在 res 文件夹下面创建 animator 文件夹,我们需要手动创建 animator 文件夹。我们的动画xml文件就存放在这里面。
  • 我们使用的AnimatorInflaterpublic static Animator loadAnimator(Context context, @AnimatorRes int id)方法加载我们的动画xml文件。

① 相关的属性

1
2
3
4
5
6
7
8
9
10
11
<animator />        //对应ValueAnimator

android:valueType //表示参数值类型,取值为intType,floatType,colorType和pathType
android:valueFrom //初始动化值;取值范围为float,int,color和path,如果取值为float对应的值样式应该为89.0,取值为Int时,对应的值样式为:89;当取值为clolor时,对应的值样式为 #333333;
android:valueTo //动画结束值;取值范围同样是float,int,color和path这三种类型的值;

android:duration //每次动画播放的时长
android:startOffset //动画激活延时;对应代码中的startDelay(long delay)函数;
android:repeatCount //动画重复次数
android:repeatMode //动画重复模式,取值为repeat和reverse;repeat表示正序重播,reverse表示倒序重播
android:interpolator//设置插值器

② 实战小例子以及运行效果

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
//value_animator.xml
<?xml version="1.0" encoding="utf-8"?>
<animator xmlns:android="http://schemas.android.com/apk/res/android"
android:valueType="intType"
android:valueFrom="231"
android:valueTo="500"

android:duration="1000"
android:startOffset="1000"
android:repeatCount="1"
android:repeatMode="restart"
/>

//Activity
public class MainActivity extends AppCompatActivity {

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

//找到要处理的控件
final View view = findViewById(R.id.btn_animation);

//加载动画文件
final ValueAnimator valueAnimator = (ValueAnimator)AnimatorInflater.loadAnimator(this, R.animator.value_animator);

//设置更新监听器,数值每次变化更新都会调用该方法
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//获得当前应该设置的值
int currentValue = (int) animation.getAnimatedValue();

//将属性数值手动赋值给对象的属性(重新设置参数)
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
layoutParams.width = currentValue;
view.setLayoutParams(layoutParams);
}
});

//开启动画
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
valueAnimator.start();
}
});
}
}

三.浮点型:ValueAnimator.oFloat()

1.作用

将初始值 以浮点型数值的形式 过渡到结束值,即估值器是浮点型估值器 - FloatEvaluator

1
public static ValueAnimator ofFloat(float... values)

和ValueAnimator.oFInt()的用法相同。

四.颜色:ValueAnimator.ofArgb()

1.作用ArgbEvaluator:

将初始值 以Argb类型的形式 过渡到结束值,即估值器是Argb型估值器 - ArgbEvaluator。

1
public static ValueAnimator ofArgb(int... values)

和ValueAnimator.oFInt()的用法相同。

五.对象:ValueAnimator.ofObject()

1.作用

将初始值 以对象的形式 过渡到结束值,需要自定义估值器(TypeEvaluator)。

1
2
3
4
5
6
7
8
9
10
11
12
public static ValueAnimator ofObject(TypeEvaluator evaluator, Object... values) {
ValueAnimator anim = new ValueAnimator();
anim.setObjectValues(values);
anim.setEvaluator(evaluator);
return anim;
}

public static ValueAnimator ofInt(int... values) {
ValueAnimator anim = new ValueAnimator();
anim.setIntValues(values);
return anim;
}

详细内容查看:Android动画-估值器(TypeEvaluator)

六.动画的控制

1
2
3
4
5
6
7
8
9
10
11
//动画开启
valueAnimator.start();
//动画结束
valueAnimator.end();
//动画取消
valueAnimator.cancel();

//动画暂停
valueAnimator.pause();
//动画唤醒
valueAnimator.resume();

结束和取消的区别是,结束会直接让动画定位到结束的位置,而取消会让动画停在当前执行的位置。

参考文章

Android:这份属性动画的核心使用类ValueAnimator学习指南请收好!