【问题标题】:Android Animate Rectangle in Custom View自定义视图中的 Android 动画矩形
【发布时间】:2014-05-06 19:29:38
【问题描述】:

我创建了一个扩展 View 的类,我将在布局中引用它以便在屏幕上绘制它。

这个类只是表示一个矩形,我希望矩形的长度一直减小到 0。

构造函数:

public CardAnimationNew(Context context, AttributeSet attrs) {
    super(context, attrs);
    mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    mPaint.setColor(getResources().getColor(R.color.card_grey_underline));
}

onMeasure:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    if (mRectangle == null) {
        mWidth = getMeasuredWidth();
        mHeight = getMeasuredHeight();
        mRectangle = new Rect(0, 0, mWidth, mHeight);
        animateRectangle();
    }
}

动画矩形:

private void animateRectangle() {
    mObjectAnimator = ObjectAnimator.ofFloat(mRectangle, "width", 5);
    mObjectAnimator.setDuration(1000);
    mObjectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator valueAnimator) {
            invalidate();
        }
    });
    mObjectAnimator.start();
}

onDraw:

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawRect(mRectangle, mPaint);
}

问题Rect 根本没有动画。它保持相同的长度。我哪里错了?

【问题讨论】:

  • 更新问题以包含一个缺失的方法 (animateRectangle)。
  • 发布你的 logcat,因为 Rect 对象没有 setWidth 方法

标签: android animation view rect


【解决方案1】:

RectEvaluator 是执行此操作的方法。基本上你可以在 Rect 上使用 ObjectAnimator 并给它一个开始和结束矩形,它会评估中间的步骤。不过,这只是 api >= 18。一篇不错的文章在这里http://cogitolearning.co.uk/?p=1451

【讨论】:

    【解决方案2】:

    根据documentation,该属性需要在您应用动画器的类中设置一个设置器。

    此名称将用于派生一个 setter 函数,该函数将被调用以设置动画值。

    重点是 Rect 没有 setWidth() 或 setHeight()

    而且 Rect 并没有 width 和 height 属性,顺便可以对它的四个坐标(topleftrightbottom)进行动画处理,达到你需要的效果。 (只需将宽度视为Math.abs(left - right),将高度视为Math.abs(top - bottom))。

    为了让它在 Rect 上工作(或者像下面例子中的 RectF - 如果你在 Rect 上需要它,只需使用 int setter 而不是 float)你需要通过添加 setter 来继承它您需要的属性

    private class AnimatableRectF extends RectF{
            public AnimatableRectF() {
                super();
            }
    
            public AnimatableRectF(float left, float top, float right, float bottom) {
                super(left, top, right, bottom);
            }
    
            public AnimatableRectF(RectF r) {
                super(r);
            }
    
            public AnimatableRectF(Rect r) {
                super(r);
            }
    
            public void setTop(float top){
                this.top = top;
            }
            public void setBottom(float bottom){
                this.bottom = bottom;
            }
            public void setRight(float right){
                this.right = right;
            }
            public void setLeft(float left){
                this.left = left;
            }
    
        }
    

    然后你可以用正常的方式为它制作动画......这里有一个例子来动画一个名为 mCurrentRect 的 AnimatableRectF 来执行翻译:

    float translateX = 50.0f;
    float translateY = 50.0f;
    ObjectAnimator animateLeft = ObjectAnimator.ofFloat(mCurrentRect, "left", mCurrentRect.left, mCurrentRect.left+translateX);
    ObjectAnimator animateRight = ObjectAnimator.ofFloat(mCurrentRect, "right", mCurrentRect.right, mCurrentRect.right+translateX);
    ObjectAnimator animateTop = ObjectAnimator.ofFloat(mCurrentRect, "top", mCurrentRect.top, mCurrentRect.top+translateY);
    ObjectAnimator animateBottom = ObjectAnimator.ofFloat(mCurrentRect, "bottom", mCurrentRect.bottom, mCurrentRect.bottom+translateY);
    animateBottom.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                            @Override
                            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                                postInvalidate();
                            }
                        });
    AnimatorSet rectAnimation = new AnimatorSet();
    rectAnimation.playTogether(animateLeft, animateRight, animateTop, animateBottom);
    rectAnimation.setDuration(1000).start();
    

    我知道这不是解决您问题的复制/粘贴解决方案,但我希望这段代码能帮助您了解如何解决您的问题!

    【讨论】:

    • 这是一个非常可靠的解决方案。感谢您的帮助!
    • 非常感谢您的回答!!我一直在寻找这样的东西!
    猜你喜欢
    • 2017-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多