2

我需要在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);
    }
}

但动画不工作,我错过了什么,或者我可以做不同的吗?

4

1 回答 1

3

你需要两个函数而不是这个。应该使用新目标来调用一个函数以获取您的值,而另一个函数应该用于实现沿途的每一步。在第一个中使用 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)”,因为您已经在 ofFloat 的第一个参数中将其设置为目标。
  • 您可能希望延迟设置字段“值”,直到动画完成。您可以使用 AnimationListener 来执行此操作,覆盖 onAnimationEnd。实际上,该字段将在 UI 表示之前设置为新的目标值。
  • "setValue" 的签名必须完全如图所示,因为这就是 ObjectAnimator.ofFloat 的工作方式:它查找指定属性的设置器,该设置器采用浮点数并返回 void。

编辑

啊,我明白了,你正在制作自己的进度条。在这种情况下,您调用 invalidate 是正确的,因为您正在覆盖 onDraw。我已经修改了上面的答案,将“setTargetValue”更改为“setProgress”。这是一个只能从这个类的外部调用的函数——谁知道进度是什么。您不希望 setProgress 调用 setValue,反之亦然。

新笔记:

  • 您应该在任何地方都使用浮点值而不是加倍,因为它们最终还是会在 RectF 中使用。如果您在数字后添加“f”,那么 Java 会将其解释为浮点数而不是双精度数,并且您不必在方程式中进行强制转换。
  • 由于您正在覆盖 onDraw,因此您的中间 setValue 函数只需要设置您的字段“值”,并使进度条无效。
于 2014-11-13T06:41:53.990 回答