同步发表于
代码获取git clone https://github.com/avenwu/support.git
在Android中动画的实现有许多不同选择,本文将扩展FrameLayout为其添加背景动画;
针对某个view做动画比较方便,这里通过自定义的属性来为一个容器类布局添加背景动画;
思路
- 动画的原理本质就是修改属性值,然后根据新的值进行绘制;
- 采用ObjectAnimator,其内部实现了对值再给定时间内的变化处理;
- 定义代表缩放圆圈的半径属性,刷新视图;
实战
根据需要,先定义float型半径mRippleRadius,并提供相应地setter、getter
private float mRippleRadius; private float getRadius() { return mRippleRadius; } private void setRadius(float radius) { this.mRippleRadius = radius; }
添加Property
PropertymRadiusProperty = new Property (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不单单可以用在常规缩放,位移动画中,也可于再自定义的属性,以及在很多需要线性变化的地方。