同步發表於 http://avenwu.net/customlayout/2015/04/06/custom_property_animation/git
代碼獲取 git clone https://github.com/avenwu/support.git
在Android中動畫的實現有許多不一樣選擇,本文將擴展FrameLayout爲其添加背景動畫;github
針對某個view作動畫比較方便,這裏經過自定義的屬性來爲一個容器類佈局添加背景動畫;canvas
根據須要,先定義float型半徑mRippleRadius,並提供相應地setter、getteride
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(); } });
最後重載繪製方法,爲容器繪製咱們但願看到的背景this
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不僅僅能夠用在常規縮放,位移動畫中,也可於再自定義的屬性,以及在不少須要線性變化的地方。.net