小文字 吃饭,睡觉,遛狗头

自定义Property属性动画

img

前言

代码获取
git clone https://github.com/avenwu/support.git 

在Android中动画的实现有许多不同选择,本文将扩展FrameLayout为其添加背景动画;

针对某个view做动画比较方便,这里通过自定义的属性来为一个容器类布局添加背景动画;

Property动画

思路

  1. 动画的原理本质就是修改属性值,然后根据新的值进行绘制;
  2. 采用ObjectAnimator,其内部实现了对值再给定时间内的变化处理;
  3. 定义代表缩放圆圈的半径属性,刷新视图;

实战

根据需要,先定义float型半径mRippleRadius,并提供相应地setter、getter

    private float mRippleRadius;
    private float getRadius() {
        return mRippleRadius;
    }

    private void setRadius(float radius) {
        this.mRippleRadius = radius;
    }

添加Property

    Property<BreathingDelegate, Float> mRadiusProperty = new Property<BreathingDelegate, Float>(Float.class, "mRippleRadius") {
        @Override
        public Float get(BreathingDelegate object) {
            return object.getRadius();
        }

        @Override
        public void set(BreathingDelegate object, Float value) {
            object.setRadius(value);
        }
    };

现在利用ObjectAnimator,实现mRippleRadius的变化,需要注意的是再每次值变化后,这里手动调用的invalidate保证视图会刷新;

            ObjectAnimator animator = ObjectAnimator.ofFloat(this, mRadiusProperty, mRippleRadius, mEndRadius);
        animator.setDuration(mDuration);
        animator.setRepeatCount(ValueAnimator.INFINITE);
        animator.setRepeatMode(ValueAnimator.REVERSE);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mTarget.invalidate();
            }
        });        

最后重载绘制方法,为容器绘制我们希望看到的背景

    public void onDraw(Canvas canvas) {
        mRippleRect.set(mBorderRect.centerX() - mRippleRadius, mBorderRect.centerY() - mRippleRadius,
                mBorderRect.centerX() + mRippleRadius, mBorderRect.centerY() + mRippleRadius);
        canvas.drawOval(mRippleRect, mPaint);
        Log.d("BreathingLayout", "onDraw=" + mRippleRect.toString());
    }

结语

ObjectAnimator/ValueAnimator不单单可以用在常规缩放,位移动画中,也可于再自定义的属性,以及在很多需要线性变化的地方。