由于是继承了ValueAnimator类
所以使用的方法十分类似:XML 设置 / Java设置
ObjectAnimator animator = ObjectAnimator.ofFloat(Object object, String property, float ....values);
// Object object:需要操作的对象
// String property:需要操作的对象的属性
// float …values:动画初始值 & 结束值(不固定长度)
// 若是两个参数a,b,则动画效果则是从属性的a值到b值
// 若是三个参数a,b,c,则则动画效果则是从属性的a值到b值再到c值
// 以此类推
anim.setDuration(500);// 设置动画运行的时长anim.setStartDelay(500);// 设置动画延迟播放时间anim.setRepeatCount(0);// 设置动画重复播放次数 = 重放次数+1// 动画播放次数 = infinite时,动画无限重复anim.setRepeatMode(ValueAnimator.RESTART);// 设置重复播放动画模式// ValueAnimator.RESTART(默认):正序重放// ValueAnimator.REVERSE:倒序回放animator.start();
// 启动动画
步骤1:在路径 res/animator 的文件夹里创建动画效果.xml文件此处设置为res/animator/set_animation.xml步骤2:设置动画参数set_animation.xml
// ObjectAnimator 采用 标签
android:valueTo=“0” // 结束值
android:valueType=“floatType” // 变化值类型 :floatType & intType
android:propertyName=“alpha” // 对象变化的属性名称
/>
在Java代码中启动动画
Animator animator = AnimatorInflater.loadAnimator(context, R.animator.view_animation);
// 载入XML动画
animator.setTarget(view);
// 设置动画对象
animator.start();
// 启动动画
此处先展示四种基本变换:平移、旋转、缩放 & 透明度
a. 透明度
mButton = (Button) findViewById(R.id.Button);// 创建动画作用对象:此处以Button为例ObjectAnimator animator = ObjectAnimator.ofFloat(mButton, "alpha", 1f, 0f, 1f);// 表示的是:// 动画作用对象是mButton// 动画作用的对象的属性是透明度alpha// 动画效果是:常规 - 全透明 - 常规animator.setDuration(5000);animator.start();

b. 旋转
mButton = (Button) findViewById(R.id.Button);// 创建动画作用对象:此处以Button为例
ObjectAnimator animator = ObjectAnimator.ofFloat(mButton, “rotation”, 0f, 360f);
// 表示的是:// 动画作用对象是mButton// 动画作用的对象的属性是旋转alpha// 动画效果是:0 - 360animator.setDuration(5000);animator.start();

c. 平移
mButton = (Button) findViewById(R.id.Button);// 创建动画作用对象:此处以Button为例
float curTranslationX = mButton.getTranslationX();
// 获得当前按钮的位置
ObjectAnimator animator = ObjectAnimator.ofFloat(mButton, “translationX”, curTranslationX, 300,curTranslationX);

// 表示的是:// 动画作用对象是mButton// 动画作用的对象的属性是X轴平移(在Y轴上平移同理,采用属性"translationY"// 动画效果是:从当前位置平移到 x=1500 再平移到初始位置animator.setDuration(5000);animator.start();d. 缩放
mButton = (Button) findViewById(R.id.Button);// 创建动画作用对象:此处以Button为例
ObjectAnimator animator = ObjectAnimator.ofFloat(mButton, “scaleX”, 1f, 3f, 1f);
// 表示的是:
// 动画作用对象是mButton
// 动画作用的对象的属性是X轴缩放
// 动画效果是:放大到3倍,再缩小到初始大小
animator.setDuration(5000);
animator.start();
在上面的讲解,我们使用了属性动画最基本的四种动画效果:透明度、平移、旋转 & 缩放
对于属性动画,其拓展性在于:不局限于系统限定的动画,可以自定义动画,即自定义对象的属性,并通过操作自定义的属性从而实现动画。
那么,该如何自定义属性呢?本质上,就是:为对象设置需要操作属性的set() & get()方法通过实现TypeEvaluator类从而定义属性变化的逻辑类似于ValueAnimator的过程
下面,我将用一个实例来说明如何通过自定义属性实现动画效果实现的动画效果:一个圆的颜色渐变

自定义属性的逻辑如下:(需要自定义属性为圆的背景颜色)步骤1:设置对象类属性的set() & get()方法
设置对象类属性的set() & get()有两种方法:通过继承原始类,直接给类加上该属性的 get()& set(),从而实现给对象加上该属性的 get()& set()通过包装原始动画对象,间接给对象加上该属性的 get()& set()。即 用一个类来包装原始对象此处主要使用第一种方式进行展示。关于第二种方式的使用,会在下一节进行详细介绍。MyView2.java
public class MyView2 extends View {
// 设置需要用到的变量
public static final float RADIUS = 100f;// 圆的半径 = 100
private Paint mPaint;// 绘图画笔private String color;
// 设置背景颜色属性// 设置背景颜色的get() & set()方法
public String getColor() {return color;
}public void setColor(String color) {this.color = color;mPaint.setColor(Color.parseColor(color));// 将画笔的颜色设置成方法参数传入的颜色invalidate();// 调用了invalidate()方法,即画笔颜色每次改变都会刷新视图,然后调用onDraw()方法重新绘制圆// 而因为每次调用onDraw()方法时画笔的颜色都会改变,所以圆的颜色也会改变
}
// 构造方法(初始化画笔)
public MyView2(Context context, AttributeSet attrs) {super(context, attrs);// 初始化画笔mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mPaint.setColor(Color.BLUE);}// 复写onDraw()从而实现绘制逻辑// 绘制逻辑:先在初始点画圆,通过监听当前坐标值(currentPoint)的变化,每次变化都调用onDraw()重新绘制圆,从而实现圆的平移动画效果@Overrideprotected void onDraw(Canvas canvas) {canvas.drawCircle(500, 500, RADIUS, mPaint);}
}
步骤2:在布局文件加入自定义View控件
activity_main.xml
步骤3:根据需求实现TypeEvaluator接口
此处实现估值器的本质是:实现 颜色过渡的逻辑。
ColorEvaluator.java
public class ColorEvaluator implements TypeEvaluator {// 实现TypeEvaluator接口private int mCurrentRed;private int mCurrentGreen ;private int mCurrentBlue ;// 复写evaluate()// 在evaluate()里写入对象动画过渡的逻辑:此处是写颜色过渡的逻辑@Overridepublic Object evaluate(float fraction, Object startValue, Object endValue) {// 获取到颜色的初始值和结束值String startColor = (String) startValue;String endColor = (String) endValue;// 通过字符串截取的方式将初始化颜色分为RGB三个部分,并将RGB的值转换成十进制数字// 那么每个颜色的取值范围就是0-255int startRed = Integer.parseInt(startColor.substring(1, 3), 16);int startGreen = Integer.parseInt(startColor.substring(3, 5), 16);int startBlue = Integer.parseInt(startColor.substring(5, 7), 16);int endRed = Integer.parseInt(endColor.substring(1, 3), 16);int endGreen = Integer.parseInt(endColor.substring(3, 5), 16);int endBlue = Integer.parseInt(endColor.substring(5, 7), 16);// 将初始化颜色的值定义为当前需要操作的颜色值mCurrentRed = startRed;mCurrentGreen = startGreen;mCurrentBlue = startBlue;// 计算初始颜色和结束颜色之间的差值// 该差值决定着颜色变化的快慢:初始颜色值和结束颜色值很相近,那么颜色变化就会比较缓慢;否则,变化则很快// 具体如何根据差值来决定颜色变化快慢的逻辑写在getCurrentColor()里.int redDiff = Math.abs(startRed - endRed);int greenDiff = Math.abs(startGreen - endGreen);int blueDiff = Math.abs(startBlue - endBlue);int colorDiff = redDiff + greenDiff + blueDiff;if (mCurrentRed != endRed) {mCurrentRed = getCurrentColor(startRed, endRed, colorDiff, 0,fraction);// getCurrentColor()决定如何根据差值来决定颜色变化的快慢 ->>关注1} else if (mCurrentGreen != endGreen) {mCurrentGreen = getCurrentColor(startGreen, endGreen, colorDiff,redDiff, fraction);} else if (mCurrentBlue != endBlue) {mCurrentBlue = getCurrentColor(startBlue, endBlue, colorDiff,redDiff + greenDiff, fraction);}// 将计算出的当前颜色的值组装返回String currentColor = "#" + getHexString(mCurrentRed)+ getHexString(mCurrentGreen) + getHexString(mCurrentBlue);// 由于我们计算出的颜色是十进制数字,所以需要转换成十六进制字符串:调用getHexString()->>关注2// 最终将RGB颜色拼装起来,并作为最终的结果返回return currentColor;}
// 关注1:getCurrentColor()
// 具体是根据fraction值来计算当前的颜色。
private int getCurrentColor(int startColor, int endColor, int colorDiff,int offset, float fraction) {int currentColor;if (startColor > endColor) {currentColor = (int) (startColor - (fraction * colorDiff - offset));if (currentColor < endColor) {currentColor = endColor;}} else {currentColor = (int) (startColor + (fraction * colorDiff - offset));if (currentColor > endColor) {currentColor = endColor;}}return currentColor;}// 关注2:将10进制颜色值转换成16进制。private String getHexString(int value) {String hexString = Integer.toHexString(value);if (hexString.length() == 1) {hexString = "0" + hexString;}return hexString;}}
步骤4:调用ObjectAnimator.ofObject()方法
MainActivity.java
public class MainActivity extends AppCompatActivity {MyView2 myView2;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);myView2 = (MyView2) findViewById(R.id.MyView2);ObjectAnimator anim = ObjectAnimator.ofObject(myView2, "color", new ColorEvaluator(),"#0000FF", "#FF0000");// 设置自定义View对象、背景颜色属性值 & 颜色估值器// 本质逻辑:// 步骤1:根据颜色估值器不断 改变 值 // 步骤2:调用set()设置背景颜色的属性值(实际上是通过画笔进行颜色设置)// 步骤3:调用invalidate()刷新视图,即调用onDraw()重新绘制,从而实现动画效果anim.setDuration(8000);anim.start();}
}
效果图

姓名:
谢林昌
csdn:
https://blog.csdn.net/m0_57471214/article/details/128065331?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22128065331%22%2C%22source%22%3A%22m0_57471214%22%7D