Drawableがアニメーションメカニズムに加わる(一)

2815 ワード

AndroidにはオリジナルのDrawableアニメーション、つまりDrawableのグループからなるフレームアニメーションがあることはよく知られています.
しかし、TextViewのDrawableにアニメーションを追加するには、この方法では明らかに通用しません.
最初は属性アニメーションでやりたいと思っていましたが、入ってもアニメーション効果はありません(属性アニメーションで実現した大神が伝言を求めている場合)
そこでGitHubでこの例を見つけました.DrawableのカスタムScaleアニメーションを実現しました.クリックしてリンクを開きます.
この文章でこの例の原理を分析する
まずDrawを書き直して、これはアニメーションを実現する核心で、先にコードを貼ります
	public void draw(Canvas canvas)
	{
		final AnimationScaleState st = mState;
		
		if(st.mDrawable == null){
			return;
		}
		
		final Rect bounds = (st.mUseBounds ? getBounds() : mTmpRect);
		
		int saveCount = canvas.save();
		canvas.scale(st.mScale, st.mScale, 
				bounds.left + bounds.width()  / 2, 
				bounds.top  + bounds.height() / 2);
		st.mDrawable.draw(canvas);
		canvas.restoreToCount(saveCount);
		
		if(st.mAnimating){
			long animTime = AnimationUtils.currentAnimationTimeMillis();
			st.mAnimation.getTransformation(animTime, st.mTransformation);
			float transformation = st.mTransformation.getAlpha();
			st.mScale = (st.mMinScale + (st.mMaxScale - st.mMinScale) 
				* (st.mInvert ? (1.0f - transformation) : transformation));
			invalidateSelf();
		}
	}

ここでstは、Drawableの様々なパラメータとステータスを格納するためにカスタマイズされたAnimationScale Stateです.
Drawableのdrawを調整するたびにCanvasにScaleを設定します
st.mAnimatingがtrueの場合、現在のScaleは再計算されます.ここでは巧みに考えています.
(0.0 f,1.0 f)のAlphaAnimationをstで定義し,そのtransformationや他のパラメータを取ってDrawable自体のグラデーションなどの効果を実現した.
計算するたびにinvalidateを調整して再描画し、Scaleアニメーションを実現します.
アニメーションを呼び出す手順を見てみましょう.
	@Override
	public void start()
	{
		if(mState.mAnimating){
			return;
		}
		
		if(mState.mInterpolator == null){
			mState.mInterpolator = new LinearInterpolator();
		}
		
		if(mState.mTransformation == null){
			mState.mTransformation = new Transformation();
		}
		else{
			mState.mTransformation.clear();
		}
		
		if(mState.mAnimation == null){
			mState.mAnimation = new AlphaAnimation(0.0f, 1.0f);
		}
		else{
			mState.mAnimation.reset();
		}
		
		mState.mAnimation.setRepeatMode(Animation.REVERSE);
		mState.mAnimation.setRepeatCount(Animation.INFINITE);
		mState.mAnimation.setDuration(mState.mDuration);
		mState.mAnimation.setInterpolator(mState.mInterpolator);
		mState.mAnimation.setStartTime(Animation.START_ON_FIRST_FRAME);
		mState.mAnimating = true;
		
		invalidateSelf();
	}

簡単に言えば、必要なパラメータを空にして、mAnimatingをtrue,invalidate()に設定します.
呼び出し方法は、外層newがDrawableになった後、TextViewに転送し、start()を呼び出すことでScaleアニメーション効果を実現
このデモが実現しているのは、ずっと動いている心の効果です
しかし、私はDemoでテストしたとき、いくつかの問題を発見しました.
1.このDemoでの効果は持続的であるため、彼はアニメーションの停止メカニズムを考慮せず、stop()関数だけを書いた.一度呼び出すだけのアニメーションについては、アニメーション開始後に適切な呼び出しタイミングを選択する必要があり、実用的ではない
2.アニメーションに柔軟性がないので、三段式アニメーションを作りたいです.
次の記事では、このDemoのメカニズムに基づいて書いた三段式アニメーションをご紹介します
Drawableにアニメーションメカニズムを追加(二)