アニメーションは View のパッケージの下にあります。なぜこのように言えるのですか?
まず単純なアニメーションアニメーション、AlphaAnimationを見てみましょう:
public class AlphaAnimation extends Animation { private float mFromAlpha; private float mToAlpha; /** * Constructor used when an AlphaAnimation is loaded from a resource. * * @param context Application context to use * @param attrs Attribute set from which to read values */ public AlphaAnimation(Context context, AttributeSet attrs) { super(context, attrs); TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.AlphaAnimation); mFromAlpha = a.getFloat(com.android.internal.R.styleable.AlphaAnimation_fromAlpha, 1.0f); mToAlpha = a.getFloat(com.android.internal.R.styleable.AlphaAnimation_toAlpha, 1.0f); a.recycle(); } /** * Constructor to use when building an AlphaAnimation from code * * @param fromAlpha Starting alpha value for the animation, where 1.0 means * fully opaque and 0.0 means fully transparent. * @param toAlpha Ending alpha value for the animation. */ public AlphaAnimation(float fromAlpha, float toAlpha) { mFromAlpha = fromAlpha; mToAlpha = toAlpha; } /** * Changes the alpha property of the supplied {@link Transformation} */ @Override protected void applyTransformation(float interpolatedTime, Transformation t) { final float alpha = mFromAlpha; t.setAlpha(alpha + ((mToAlpha - alpha) * interpolatedTime)); } @Override public boolean willChangeTransformationMatrix() { return false; } @Override public boolean willChangeBounds() { return false; } /** * @hide */ @Override public boolean hasAlpha() { return true; }}
コードは非常に単純で、そのコアコードは
@Overrideprotected void applyTransformation(float interpolatedTime, Transformation t) { final float alpha = mFromAlpha; t.setAlpha(alpha + ((mToAlpha - alpha) * interpolatedTime));}
にあります。
interpolatedTimeを通じてアルファ値を継続的に変更します。ビューの透明度変化のアニメーション効果を確認できます。そこで問題は、applyTransformation メソッドを呼び出しているのは誰かということです。コードを追跡すると、applyTransformation が
public boolean getTransformation(long currentTime, Transformation outTransformation){}
で呼び出されていることがわかります。特に考える必要はありません。getTransformation は View の startAnimation でトリガーされる必要があります。
そうですよね?
public void startAnimation(Animation animation) { animation.setStartTime(Animation.START_ON_FIRST_FRAME); setAnimation(animation); invalidateParentCaches(); invalidate(true); }
ここで View が再描画されるので、View の booleandraw(Canvas Canvas, ViewGroupparent, long drawingTime) メソッドが実行されます。なぜ onDraw ではなくdraw するのかというコメントを見てみましょう。
/** * This method is called by ViewGroup.drawChild() to have each child view draw itself. * This draw() method is an implementation detail and is not intended to be overridden or * to be called from anywhere else other than ViewGroup.drawChild(). */
がdraw()メソッドにあるため、AnimationはgetTransformationを実行する必要があります。これがAnimationの実装原則です。
しかし、これは私たちにとってあまり意味がないようです。確かに、私たちはアニメーションの作成者ではないので、私たちと皆さんはアニメーションの使い方を知るだけで十分です。それでは、ウォームアップしてみましょう。
アニメーションの使用
Android では、AlphaAnimation、RotateAnimation、ScaleAnimation、および TranslateAnimation の 4 つのアニメーション アニメーション効果が定義されています
AlphaAnimation を例として使用方法を簡単に説明します。 :final Animation a = getAnimation();if (a != null) { more = drawAnimation(parent, drawingTime, a, scalingRequired); concatMatrix = a.willChangeTransformationMatrix(); if (concatMatrix) { mPrivateFlags3 |= PFLAG3_VIEW_IS_ANIMATING_TRANSFORM; } transformToApply = parent.getChildTransformation();}
わかりました、1 つのビューのアニメーションが実現され、他の 3 つのアニメーション効果も同様で、非常にシンプルです。ここでは繰り返しませんが、アニメーション効果を自分で定義する方法、またはケースを通して説明する方法に焦点を当てましょう。
ボタン拡大のアニメーション効果を実現します。ここでの拡大は拡大できませんが、システムがすでに拡大を定義しており、ScaleAnimation でそれを実現できるため、意味がありません。これは、Animation を継承することです。
2 番目のステップは、applyTransformation メソッドを書き換えます。3 番目のステップは、終了しました。
コードは次のとおりです:
AlphaAnimation animation = new AlphaAnimation(1,0);animation.setDuration(2000) ;animation.setRepeat(2) ;view.startAnimation(animation);
使用コード:
/** * Created by moon.zhong on 2015/4/23. */public class ScaleAnimation extends Animation { private View mTarget ; private int mOriginWidth ; private int mTargetWidth; private ViewGroup.LayoutParams mParams ; public ScaleAnimation(int mTargetWidth, View target) { this.mTarget = target; this.mOriginWidth = mTarget.getMeasuredWidth(); this.mTargetWidth = mTargetWidth; if (mOriginWidth == 0 ){ mTarget.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { mTarget.getViewTreeObserver().removeOnPreDrawListener(this); mOriginWidth = mTarget.getMeasuredWidth() ; return false; } }); } mParams = target.getLayoutParams() ; } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { /*interpolatedTime * 变化范围 * 0~1 * */ mParams.width = (int) (mOriginWidth + (mTargetWidth - mOriginWidth)*interpolatedTime) ; mTarget.setLayoutParams(mParams); }}
レンダリング:
比較のための別のストレッチレンダリング:
要約:
このブログの主な知識ポイントは次のとおりです:
1. View で動作するアニメーションのアプリケーション シナリオ
public void startAnimation(View view){ final float density = getResources().getDisplayMetrics().density; int width = (int) (300 * density); ScaleAnimation animation = new ScaleAnimation(width,mTargetView) ; animation.setDuration(2000); mTargetView.startAnimation(animation); }
この形式、もちろん XML を読み取る形式もありますここでは利用できません
3. カスタム アニメーション
applyTransformation メソッドを書き換えます
デモ ソース コード
http://download.csdn.net/detail/jxxfzgy/8634819