当value
属性更改时,我需要设置进度条值更改的动画,我的自定义视图如下所示,
public class ProgressBar extends View {
public ProgressBar(Context context) {
this(context, null);
}
public ProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
ObjectAnimator animator;
double value = 50;
public double getValue() {
return value;
}
public void setTargetValue(double targetValue) {
animator = ObjectAnimator.ofFloat(this, "value", (float) this.value,(float) targetValue);
animator.setDuration(1500);
animator.start();
this.value = targetValue;
}
public void setValue(double tempValue) {
setTargetValue(tempValue);
this.invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setStrokeWidth(3);
RectF borderRectF = new RectF(50,100,400,200);
RectF backgroundRectF = new RectF(53,103,397,197);
RectF filledRectF = new RectF(53,103,53,197);
paint.setColor(Color.LTGRAY);
canvas.drawRect(borderRectF, paint);
paint.setStrokeWidth(0);
paint.setColor(Color.WHITE);
canvas.drawRect(backgroundRectF, paint);
paint.setColor(Color.BLUE);
filledRectF = getfilledRect();
canvas.drawRect(filledRectF, paint);
}
private RectF getfilledRect(){
float filledValue = (float)(53+(3.44 * this.value));
filledValue = Math.min(filledValue,397);
return new RectF(53,103,filledValue,197);
}
}
但动画不起作用,是我错过了什么,还是我可以做得不同?
最佳答案
你需要两个函数而不是这个。应该使用新的值目标调用一个函数,并使用另一个函数来实现过程中的每个步骤。在第一个步骤中使用objectanimator,它将为每个增量步骤多次调用第二个函数。这样地:
public void setProgress(float progress) {
animator = ObjectAnimator.ofFloat(this, "value", this.value, progress);
animator.setDuration(1500);
animator.start();
}
public void setValue(float value) {
this.value = value;
invalidate();
}
private RectF getfilledRect() {
float filledValue = 53f + (3.44f * this.value);
filledValue = Math.min(filledValue, 397f);
return new RectF(53f, 103f, filledValue, 197f);
}
几点注意事项
您不需要调用“setTarget(this)”,因为您已经在要卸载的第一个参数中将其设置为目标。
您可能需要延迟设置字段“值”,直到动画完成。您可以使用AnimationListener来执行此操作,覆盖AnimationEnd。实际上,在ui表示这个值之前,该字段将被设置为新的目标值。
“setValue”的签名必须与所示完全相同,因为这就是objectanimator.offload的工作原理:它寻找一个名为property的setter,该setter接受float并返回void。
编辑
啊,我明白了,你自己在进步吧。在这种情况下,调用invalidate是正确的,因为您正在重写ondraw。我修改了上面的答案,将“setTargetValue”改为“setProgress”。这是一个只应该从类外部调用的函数——不管谁知道进程是什么。您不希望setprogress调用setvalue,反之亦然。
新注释:
您应该在任何地方都使用浮点值,而不是double,因为它们最终会在rectf中使用。如果在数字后面加上“f”,那么java将其解释为一个浮点数,而不是一个双精度数,并且不必在公式中进行强制转换。
由于您正在重写OnDraw,您的中间setValue函数只需要设置字段“value”,并使进度条无效。