作者:opLW 记录平时所学内容
参考:启舰大神的《Android自定义控件开发入门与实战》
属性动画–ValueAnimator的使用
目录
1.属性动画和视图动画的种类
2.属性动画与视图动画的区别
3.使用ValueAnimator
4.自定义Interpolator和Evaluator
1.属性动画和视图动画的种类
- 属性动画:ValueAnimator和ObjectAnimator
- 视图动画:TweenAnimation(补间动画)和FrameAnimation(逐帧动画)
2.属性动画与视图动画的区别
- 引入时间不同: ViewAnimation是API1时引入的,PropertyAnimation是API11引入的,即Android3.0引入的。
- 所在包不同: ViewAnimation所在的包为android.view.animation,PropertyAnimation所在的包一般为android.animation.
- 动画类的命名不同: ViewAnimation中动画类的命名都是XXXXAnimation,而 PropertyAnimation中动画类命名都是XXXXAnimatior
3.使用ValueAnimator
- 基本用法ValueAnimator
ValueAnimator animator = new ValueAnimator();
animator.addUpdateListener(new AnimatorUpdateListener() {
//重写其中的方法
@Override
public void onAnimationUpdate(ValueAnimator animation){
int curValue = (Interger)animation.getAnimatedValue(); //此处根据具体的类型进行强转
//得到变化的值便可修改控件的left,top,right,bottom,从而形成动画
tv.layout(curValue, curValue, curValue+tv.getWidth(), curValue+tv.getHeight());
})
animator.setDuration(1000) //单位是毫秒
animator.start()
结论:
- ValueAnimatior只负责对指定区间进行动画运算。
- 我们需要对运算过程进行监听,然后对控件执行动画操作,即动态的改变控件的属性值。
- 常用函数
(1)ofInt()和ofFloat()
public static ValueAnimator ofInt(int...values);
public static ValueAnimator ofFloat(float...values);
1)不同点: 两者的区别是添加监听时返回值的类型不同。
2)相同点: 两者的形参都是一个不定长参数,我们可以通过形如ofInt(100, 50, 200)构造复杂的动画渐变。
(2)其他常用函数。
setDuration(long duration) //设置动画时长,单位是毫秒
getAnimatedValue() //通过监听获取动画的变化值,返回值是Object,注意根据实际的类型进行转换
start() //开始动画
cancel() //取消动画
setRepeatMode(int mode) //设置动画的循环模式,有RESTART和REVERSE两种类型
setRepeatCount(int value) //设置动画的循环次数,ValueAnimator.INFINITE代表无限循环
SetStartDelay(long startDelay) //设置动画延迟
setInterpolator(TimeInterpolator interpolator) //设置插值器
setEvaluator(TypeEvaluator<T> evaluator)
(3)添加和移除监听器
/*
监听器一:监听动画过程中值的实时改变
添加方法:animator.addUpdateListener(listener)
移除方法:removeUpdateListener(listener)
removeAllUpdateListeners()
*/
public static interface AnimatorUpdateListener {
void onAnimationUpdate(ValueAnimator animation);
}
/*
监听器二:监听动画变化的四个状态值
添加方法:animator.addListener(listener)
移除方法:removeListener(listener)
removeAllListeners()
*/
public static interface AnimatorListener {
void onAnimationStart(Animator animation); //动画开始
void onAnimationEnd(Animator animation); //动画结束
void onAnimationCancel(Animator animation); //动画被取消
void onAnimationRepeat(Animator animation); //动画重复
}
4.自定义Interpolator和Evaluator
[外链图片转存失败(img-o780ebhw-1563697898904)(http://po8upthot.bkt.clouddn.com/Ft7UCGXHXYtd9eHUPiRxPzMLEHOV)]
- 从定义动画的数值区间到在AnimatorUpdateListener中得到当前动画所对应数值的整个过程
(1)ofInt(0, 400)制定动画的区间。
(2)插值器: 返回数值是一个小数,在这里可以改变动画的进度。
(3)Evaluator: 在上一步我们拿到的是一个小数值,真正实现我们想要的具体的值,需要在这里进行转化。
(4)通过设置监听得到我们想要的值
下面讲讲起到影响动画变化的主要因素:
- 自定义Intetpolator
(1)系统已经自带了很多有用的插值器(把Interpolator叫做插值器),如LinearInterpolator(匀速变化),AccelerateInterpolator(加速变化)等等。
(2)为了实现更加复杂的动画效果就需要自定义插值器,插值器起到一个中间干涉的作用。
(3)先看看系统自带的插值器LinearInterpolator的主要代码:
public class LinearInterpolator extends BaseInterpolator {
public float getInterpolation(float input) {
return input;
}
}
//下面是继承的关系
abstract public class BaseInterpolator implements Interpolator
public interface Interpolator extends TimeInterpolator
public interface TimeInterpolator {
float getInterpolation(float input);
}
可以看到LinearInterpolator实现了TimeInterpolator的方法getInterpolation(float input)。
A 参数: input是一个float类型的值,取值从0.0到1.0,0.0代表的是动画刚开始,1.0代表的是动画结束。
B 返回值: 表示当前实际想要的值,取值可以大于1或者小于0,超过1表示已经超过目标值,小于0表示小于开始的位置。
C 自定义的要点: 参数从0.0到1.0是一个恒定匀速的过程,我们可以改变的只是返回的值,从而使动画按我们的要求的速度来变化。这个时候数学的重要性就体现了:?
4)自定义例子:
public class MyInterpolator implements TimeInterpolator {
@Override
public float getInterpolation(float input) {
return 1 - input; //通过修改返回值,将动画开始和结束进行了颠倒
}
}
- 自定义Evaluator
(1)概述: 每一种变化类型都有特定的Evaluator,这些是系统为我们定义好的。
变化类型 | Evaluator |
---|---|
ofInt() | IntEvaluator, ArgbEvaluator(针对颜色值) |
ofFloat() | FloatEvaluator |
特别的: ofInt()可以获取颜色变化过程的值.如ofInt(0xffffffff, 0x00000000)从白色变化到黑色。下面是ArbgEvaluator的部分源码:
float startA = ((startInt >> 24) & 0xff) / 255.0f;
float startR = ((startInt >> 16) & 0xff) / 255.0f;
float startG = ((startInt >> 8) & 0xff) / 255.0f;
float startB = ( startInt & 0xff) / 255.0f;
有什么注意点呢?
1)从中可以看出右移的位数都是8的倍数,因此我们的颜色值都应该是argb_8888格式的,例如黑色只能用0x00000000,而不是0x0000;
2)每个颜色值都应该包含透明值A;
(2)自定义
1)先看系统自带的两个Evaluator.
public class FloatEvaluator implements TypeEvaluator<Number> {
public Float evaluate(float fraction, Number startValue, Number endValue) {
float startFloat = startValue.floatValue();
return startFloat + fraction * (endValue.floatValue() - startFloat);
}
}
public class IntEvaluator implements TypeEvaluator<Integer> {
public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
int startInt = startValue;
return (int)(startInt + fraction * (endValue - startInt)); //注意强转为Int
}
}
//共同实现的接口
public interface TypeEvaluator<T> {
public T evaluate(float fraction, T startValue, T endValue);
}
2)显而易见,要想实现自己的Evaluator就要实现TypeEvaluator这个接口。
A fraction: 这个参数即Interpolator中返回的值。
B startValue: 这个参数是我们通过ofInt(100, 400)设置动画中的100。
C endValue: 这个参数是我们通过ofInt(100, 400)设置动画中的400。
D 返回值: 当前动画对应的具体指,这个数值我们可以在设置监听的AnimatorUpdateListener中得到。
下面看个例子:
(int)(200 + startInt + fraction * (endValue - startInt))
加上一个200的值,那么ofInt(100,400)的变化值就会从100到400,变成300到600
结束
简单记录了ValueAnimator的使用,希望能和各位一起学习!
好记性不如烂笔头!!
万水千山总是情,麻烦手下别留情。
如若讲得有不妥,文末留言告知我,
如若觉得还可以,收藏点赞要一起。
opLW原创七言律诗,转载请注明出处