将 ValueAnimator 值输出到 onDraw

Getting ValueAnimator value out to onDraw

我对本页中的说明感到困惑 this。正在处理以下功能。

PropertyValuesHolder propertyRadius = PropertyValuesHolder.ofInt(PROPERTY_RADIUS, 0, 150);
PropertyValuesHolder propertyRotate = PropertyValuesHolder.ofInt(PROPERTY_ROTATE, 0, 360);

animator = new ValueAnimator();
animator.setValues(propertyRadius, propertyRotate);
animator.setDuration(2000);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        radius = (int) animation.getAnimatedValue(PROPERTY_RADIUS);
        rotate = (int) animation.getAnimatedValue(PROPERTY_ROTATE);
        invalidate();
    }
});
animator.start();

他说调用这个方法来做旋转。正如我所做的那样,在全局中声明“radius”和“rotate”变量并将下面的代码放在“onDraw”方法中,因此无效将更新 Canvas.

canvas.rotate(rotate, viewWidth, viewHeight);

问题:我似乎无法从下面的代码中获取“半径”或“旋转”变量。当我在 OnDraw 中插入日志以检查“旋转”值时,它一直返回“0”。我还在学习这个 canvas 东西。

 public void onAnimationUpdate(ValueAnimator animation) {
        radius = (int) animation.getAnimatedValue(PROPERTY_RADIUS);
        rotate = (int) animation.getAnimatedValue(PROPERTY_ROTATE);
        invalidate();
    }

更新

这是我的完整代码:

public class DrawingShapes extends View {
    private String PROPERTY_ROTATE = "PROPERTY_ROTATE", PROPERTY_RADIUS = "PROPERTY_RADIUS";

    private Context mContext;

    private int radius, rotate;


    public DrawingShapes(Context context) {
        super(context);
    }

    public DrawingShapes(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawAnim();
        Log.i("TAG", "checking DrawingShapes rotate = " + rotate);

    }
    

    public static int convertDpToPixel(Context context, int idp) {
        return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, (float) idp, context.getResources().getDisplayMetrics()));
    }

    public void drawAnim() {
        PropertyValuesHolder propertyRadius = PropertyValuesHolder.ofInt(PROPERTY_RADIUS, 0, 150);
        PropertyValuesHolder propertyRotate = PropertyValuesHolder.ofInt(PROPERTY_ROTATE, 0, 360);

        ValueAnimator animator = new ValueAnimator();
        animator.setValues(propertyRadius, propertyRotate);
        animator.setDuration(100);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                radius = (int) animation.getAnimatedValue(PROPERTY_RADIUS);
                rotate = (int) animation.getAnimatedValue(PROPERTY_ROTATE);
                Log.i("TAG", "checking DrawingShapes rotate = " + rotate);
                invalidate();
            }
        });

        animator.start();
    }
    
}

您在 onDraw 开始播放动画,这没有任何意义。 onDraw 应该只用于 绘图 ,而不是其他任何东西。

要强调为什么它会毫无意义,请考虑您的代码实际在做什么:

onDraw 启动动画,重复调用 invalidate。然后触发 onDraw 再次被调用,然后启动另一个动画,重复调用 invalidate, ...., 等等

您应该在希望动画开始时开始动画,例如在实例化视图时,或者在它响应某种触发器时手动开始。例如:

class DrawingShapes ... {

    private int radius;

    DrawingShapes(...) {

        ...
        startAnimation();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        
        drawCircleWithRadius(radius);
    }

    private void startAnimation() {

        ValueAnimator animator = new ValueAnimator();
        ...
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {

                radius = ...
                invalidate();
            }
        });

        animator.start();
    }
}