原文 2011-02-24 ハニカムのアニメーションは 2011.02 に公開されました (3.0 のリリースと同期)。作者は、グラフィックスとアニメーションの研究を専門とする Android 開発者である Chet Haase です。彼から学ぶ 個人ブログ graphics-geek.blogspot.com 関連トピックに関するブログ投稿をさらにお読みください。
翻訳者は次のように述べています:
この記事では、ビューの移動、拡大縮小、回転、フェードを実現できる android.view.animation がすでに存在します。なぜそれがまだ必要なのでしょうか。 ? 3.0 で新しい API android.animation を導入しますか? 新しい API はどのような新機能をもたらしますか? 次に、これらの新機能の強力な利便性をさらに実証します。2011年2月にリリースされましたが、現在は2016年1月末です。ペースは5年遅いですが、3のアニメーション。初心者(私)にとっては学ぶ価値があります。
この記事は全文訳でも、逐語訳でもありませんが、私自身の勉強メモとして、整理してメモした「要約訳」と言えます。
ドキュメントとコードを一緒に読んで、相互にサポートし、理解することを強くお勧めします。同時に、ApiDemos で関連するサンプルを実行してアニメーション効果を観察し、コードを変更する必要があります。パラメータを確認し、アニメーション効果を観察します。一連の記事:
Android アニメーションを学ぶには?
Android サンプル ApiDemos から android.animation API の使用法を学びます
Android アニメーション インターポレーター - Android アニメーション インターポレーター分析
weiyi.li li2.me 2016-01-28 ~ 2016-02-01
Honeycomb によって導入された新機能の 1 つは、新しいアニメーション システム android.animation です。オブジェクト アニメーションとプロパティ アニメーションの実装がこれまでより簡単になりました。
Honeycomb の前は、
ビューの移動、拡大縮小、回転などのアニメーションは android.view.animation によって実装されていました。 、グラデーションフェード;
AnimationSet の組み合わせにより複数のアニメーションを配置します。
コンテナがサブビューを配置するときにアニメーションを自動的にずらします。すべてのサブビュー アニメーションの開始時間 (記事の最後に注記があります )
インターポレーターを使用します (インターポレーター、アニメーションのレートを定義するために使用されます)。 記事の最後に AccelerateInterpolator や BounceInterpolator などのコメントがあります )。これにより、アニメーションが一定の速度で変化することがなくなり、より自然に見えます。
上で述べたように、ハニカムは以前から ビュー アニメーション を実装できますが、それだけです。以前は、ハニカム アニメーションはビュー オブジェクト (ビュー オブジェクト) 上でしか動作できず、一部の主要な機能のサポートは、Drawable の位置や背景色などのビュー プロパティに対しては無力です。
前のアニメーションは、ターゲット ビューの視覚効果 (見た目) を変更するだけで、ビュー オブジェクトのプロパティは変更しません。たとえば、アニメーション TranslateAnimation と setFillAfter(true) を使用してボタンの位置を変更すると、アニメーションは新しい位置でボタンを再描画するだけで、親ビュー内のボタンの位置を変更することはできません。つまり、新しい場所でボタンをクリックしても効果はありません。
上記の理由 (および言及されていないその他の理由) に基づいて、Honeycomb は、プロパティ アニメーション の概念に基づいた新しいアニメーション メカニズムを提供します。
新しいアニメーション メカニズムは、ビュー オブジェクトのみ、オブジェクトの特定のプロパティのみ、または視覚効果に限定されません。実際、一定期間後に 値 を変更し、それらの変更された値を 任意の ターゲット オブジェクトとプロパティに設定することがすべてです。
そのため、ビューを移動したりグラデーションしたり、Drawable の背景色を動的に変更したり、任意のデータ型の値を動的に変更したりすることができます。新しいメカニズムを伝える: 新しいメカニズムはアニメーション プロセス値を計算し、それをターゲット オブジェクトと属性に設定できます。
つまり、新しいメカニズムでボタンを動かすと、実際にボタンの位置が移動します。
次に、新しいメカニズムのいくつかの主要なクラスを簡単に紹介し、必要に応じてサンプル コードを示します。新しいメカニズムがどのように機能するかについて詳しく知りたい場合は、SDK サンプル ApiDemos を研究してください (注釈: Android サンプル ApiDemos の android.animation API の使用方法については、私の記事を参照してください)
Animator は、新しいアニメーション メカニズムのスーパークラスです。サブクラス ValueAnimator はコア タイミング エンジンであり、サブクラス AnimatorSet は複数のアニメーションを 1 つのアニメーションに配置するために使用されます。 Animator は通常、直接使用されませんが、持続時間、開始遅延、リスナーなどの一部のプロパティとメソッドはサブクラスに共通です。
アニメーションの終了時に何らかの操作を実行したい場合、リスナーは非常に便利です。重要。アニメーションのライフサイクル イベントをリッスンするには、AnimatorListener インターフェイスを実装し、それをアニメーターに登録する必要があります。たとえば、
anim.addListener(new Animator.AnimatorListener() { public void onAnimationStart(Animator animation) {} public void onAnimationEnd(Animator animation) { // do something when the animation is done } public void onAnimationCancel(Animator animation) {} public void onAnimationRepeat(Animator animation) {} });
もちろん、特定のイベントをリッスンするだけでよいことを考慮すると、インターフェイスの他のメソッドをオーバーライドする必要がないことを意味しますが、スペースを占有すると「コードの単純さの制御」がおかしくなる可能性があります。アダプター クラス AnimatorListenerAdapter を使用すると、必要なメソッドのみをオーバーライドできます。
anim.addListener(new AnimatorListenerAdapter() { public void onAnimationEnd(Animator animation) { // do something when the animation is done } });
ValueAnimator は、新しいメカニズム全体の「主力」です。内部タイミング ループ (タイミング ループ 記事の最後にコメントがあります ) を実行するため、プログラム内のすべてのアニメーションがタイミング パルスごとに実行されます (タイミング パルス コメントがあります)記事の最後にある ) が発生し、現在のアニメーション プロセス値が時間の経過とともに計算され、ターゲット オブジェクトとプロパティに設定されます。
これを行うのに役立ついくつかのコア機能があります。
各アニメーションのタイミングの詳細 (開始/停止時間、持続時間、現在のアニメーションの長さなど) を認識します。
アニメーションが繰り返されるかどうかを確認します。
現在のアニメーション プロセス値が計算された後、コールバックは次のように登録されます。そのリスナー (AnimatorUpdateListener);
には、さまざまな型の値を計算する機能 (TypeEvaluator) があります。
プロパティ アニメーションは、アニメーション プロセス値を計算し、その値をターゲット オブジェクトとプロパティに設定する 2 つのステップで構成されます。 ObjectAnimator (後述) は ValueAnimator を直接継承しているため、属性アニメーションの実装が容易になります。ただし、次の状況では ValueAnimator を使用する方が便利です。
オブジェクトが特定のプロパティの setter メソッドを提供していない場合 (注釈: があるかどうかは関係ありません。理由は、後ほど ObjectAnimator について説明するときにわかります。
アニメーション プロセス値を複数のプロパティに設定したい場合。 🎜>
上で述べたように、
ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f); anim.setDuration(500); anim.start();
。では、アニメーションが発生したかどうかをどのようにして知ることができるのでしょうか? ——答えはリスナーです。リスナー AnimatorUpdateListener を実装し、ValueAnimator インスタンスに登録すると、アニメーション フレームごとに呼び戻すことができます (アニメーション フレーム 記事の最後にコメントがあります )現在のアニメーション値を取得するには:
浮動小数点数に加えて、整数などの他のタイプの値をアニメーション化することもできます:anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { public void onAnimationUpdate(ValueAnimator animation) { Float value = (Float) animation.getAnimatedValue(); // do something with value... } });
XML ファイルでも実装できます同じアニメーション:
ValueAnimator anim = ValueAnimator.ofInt(0, 100);
新しいメカニズムには、関連する計算メソッドが組み込まれているため、整数と浮動小数点数のアニメーション プロセス値を計算する方法がわかります。 Point、Rect、さらにはカスタム データなどの他のタイプのデータの場合、新しいメカニズムはその計算方法を知りませんが、TypeEvaluator (後述) を通じて、アニメーション プロセス値を計算する責任がユーザーに引き継がれます。
<animator xmlns:android="http://schemas.android.com/apk/res/android" android:valueFrom="0" android:valueTo="100" android:valueType="intType"/>
アニメーションの長さに加えて、次のアニメーション パラメーターも設定できます。
Point p0 = new Point(0, 0); Point p1 = new Point(100, 200); ValueAnimator anim = ValueAnimator.ofObject(pointEvaluator, p0, p1);
この例では、アニメーションの終了値のみが設定されていますが、開始値はデフォルトでプロパティの現在の値。
ObjectAnimator.ofFloat(myObject, "alpha", 0f).start();
XML ファイルでも同じアニメーションを定義できます:
ただし、ターゲット オブジェクトを XML で設定することはできません。アニメーション リソースをロードした後にコードでのみ設定できます:
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:valueTo="0" android:propertyName="alpha"/>
ObjectAnimator を使用する前に、プロパティとその set/get メソッドに関する暗黙の前提を理解する必要があります。この仮定は次のことを意味します:
ObjectAnimator anim = AnimatorInflator.loadAnimator(context, resID); anim.setTarget(myObject); anim.start();
がプロパティ名に関連するパブリック set メソッド
を持ち、プロパティが適切なデータ型を持つことを前提とします。また、上記の例のように、ObjectAnimator の構築時に終了値のみが設定されている場合、アニメーション メカニズムはプロパティの現在の値を認識している必要があります。したがって、オブジェクトには、対応するパブリック get メソッド も必要です。適切なタイプのデータを返します。 したがって、アルファに関する上記のコード例を正常に実行したい場合、オブジェクト myObject には 2 つのパブリック メソッドが必要です。
つまり、オブジェクトがその To use になりたい場合は、特定のプロパティの ObjectAnimator を使用する場合、オブジェクトはアニメーション メカニズムの「説明されていない」条件 (プロパティのパブリック set/get メソッドを提供する) を満たしている必要があります。
特别说明:set/get 方法在 animation 运行时调用,因此它们和动画之间是非常弱的关系。而如果你的程序中又没有任何地方显示地调用这些 set/get 方法,而你恰好又使用了 ProGuard(代码混淆工具)或者其它代码优化工具(code stripping 代码剥离),那么这些工具便不会知道 set/get 在运行时被调用,很有可能就被剥离掉了。所以当你使用这些工具时,你有义务确保这些 set/get 方法的存在。
敏锐的读者可能已经发现了新动画机制的「瑕疵」:围绕属性做文章的新机制,如何处理那些连一个 public set/get 属性方法都没有的视图对象呢?
好问题!继续读下去。
类 View(查阅文档中 Animation 相关的说明) 在 Honeycomb 中得到了升级,增添了很多新属性,可以通过 set/get 方法访问这些属性,使得新动画机制可以应用于视图对象:
translationX 和 translationY
rotation, rotationX, 和 rotationY
scaleX 和 scaleY
pivotX 和 pivotY
x 和 y
alpha
AnimatorSet 用来把多个动画编排成一个动画(作用类似于3.0以前的 AnimationSet)。比如你想编排一个这样的动画:先渐隐一个视图,结束后从侧边滑入另一个视图,滑入的同时渐显出来。为了实现这样的编排,首先需要拆分成几个独立的动画,接下来就有好几种选择了:(1) 在正确的时间手动播放对应的动画,或者给每个动画设置合适的播放延迟,总之你需要显示地、主动地设置合适的时间;(2) 如果觉得时间不好掌控,或者嫌麻烦,就使用 AnimatorSet,它提供的 APIs 使这些变得很简单:
同时播放:playTogether(Animator...);
顺序播放:playSequentially(Animator...);
通过 AnimatorSet.Builder 设置动画间的相对关系:with(), before(), after();
play(Animator) 会创建一个 Builder;
因此上述动画可以这样实现:
ObjectAnimator fadeOut = ObjectAnimator.ofFloat(v1, "alpha", 0f); ObjectAnimator mover = ObjectAnimator.ofFloat(v2, "translationX", -500f, 0f); ObjectAnimator fadeIn = ObjectAnimator.ofFloat(v2, "alpha", 0f, 1f); AnimatorSet animSet = new AnimatorSet().play(mover).with(fadeIn).after(fadeOut);; animSet.start();
也可以在 XML 文件中实现上述动画。
上述 ValueAnimator 一节有说过一段话:「新机制知道如何计算整数和浮点数的动画过程值,这是因为其内置了相关的计算方法。而对于其它类型的数据,比如 Point, Rect, 甚至自定义数据,新机制不知如何计算,但通过 TypeEvaluator,转手就把计算动画过程值的责任交给了你。」
而 TypeEvaluator 是只定义了一个方法的接口:
public interface TypeEvaluator<T> { public T evaluate(float fraction, T startValue, T endValue);}
内置的处理浮点数的 FloatEvaluator 继承了该接口,而它的方法仅仅是 y = kx + b 的实现,非常简单:
public class FloatEvaluator implements TypeEvaluator { public Object evaluate(float fraction, Object startValue, Object endValue) { float startFloat = ((Number) startValue).floatValue(); return startFloat + fraction * (((Number) endValue).floatValue() - startFloat); } }
那么这个方法是如何被调用到的呢?
// ValueAnimator.class void animateValue(float fraction) { // 篡改播放进度 turns the elapsed fraction into an interpolated fraction. fraction = mInterpolator.getInterpolation(fraction); for (int i = 0; i < numValues; ++i) { // 根据篡改后的进度计算动画过程值 turn the interpolated fraction into an animated value. // 继续追代码,会追到 PropertyValuesHolder 和 Keyframes 两个类,深究不下去了 orz TODO mValues[i].calculateValue(fraction); } }
如果不是浮点数和整数,或者内置的处理整数的 IntEvaluator 和处理浮点数的 FloatEvaluator 不能满足你的要求,则必须显示地设置 TypeEvaluator,可以调用 setEvaluator(TypeEvaluator) 或者通过构造器 ValueAnimator.ofObject(TypeEvaluator, Object...),比如计算 Point 的动画过程值:
public class PointEvaluator implements TypeEvaluator { public Object evaluate(float fraction, Object startValue, Object endValue) { Point startPoint = (Point) startValue; Point endPoint = (Point) endValue; return new Point(startPoint.x + fraction * (endPoint.x - startPoint.x), startPoint.y + fraction * (endPoint.y - startPoint.y)); } }
现在使用它把在 ValueAnimator 这节内容中提到的例子补充完整:
Point p0 = new Point(0, 0); Point p1 = new Point(100, 200); ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), p0, p1);
译注:这篇文章发布于 2011.02,针对于 API level 11 的 3.0 系统,此后 L18 加入了 RectEvaluator, L21 加入了 PointFEvaluator、IntArrayEvaluator、FloatArrayEvaluator。
所以上述几次提到的「不知道如何计算 Rect 的动画过程值」也并不是错误的,要特别注意技术文章的时效,查阅最新的文档和代码,以相互佐证。
查阅 TypeEvaluator Known Indirect Subclasses。
还有非常多的新特性可以说,但是限于文章篇幅和时间,这里就不再继续下去了。现在你应该和 ApiDemos「耍一耍」,潜心研究代码。
动画重复的一些特性;
动画生命周期事件的监听器;
在两个值以上做动画;
使用 Keyframe 定制更复杂的时值序列(time/value);
使用 PropertyValuesHolder 指定多个属性并行动画;
使用 LayoutTransition 定制简单的布局动画;
......
アニメーション メカニズムは、英語では主に「新しいメカニズム」と呼ばれます。この記事では、3.0 android.animation の導入について言及しています。システムというと Android システムと混同されやすいため、ここで「アニメーション システム」と訳すのは適切ではないように感じます。
この記事の文脈における「新しいメカニズム」とは、特に android.animation.
タイミング ループを指します。
android.animation.ValueAnimator は、タイミング ループを維持するための Runnable を実装する静的内部クラス AnimeHandler を定義し、それによってアニメーションが「動く」ことができる理由は、タイミング パルスが開始できることです。アニメーションの「心臓部」と考えられており、その機能はマイクロコントローラーの水晶発振器に似ています。
タイミングがパルスされるたびに、各アニメーションは、アニメーション、Interpolator、および TypeEvaluator の現在時間に基づいてアニメーションのプロセス値を計算します。
詳細については、http://li2.me/2016/01/android-animation-interpolator.html をご覧ください。
アニメーション フレーム、各フレーム、各フレーム
アニメーション フレーム (ここではフレームをフレームとして理解してはなりません)。
上記のタイミング ループについて説明した際、各タイミング パルスが新しいアニメーション値を計算すると述べました。新しい値はアニメーションが変更されたことを意味するため、フレームごとのアニメーションとして理解できます。
アニメーション処理値、アニメーション中間値。
属性アニメーションの本質は「値の変更」です。
コンストラクター (または XML) を通じてアニメーションの開始値と終了値を指定します。 🎜>
Interpolator と TypeEvaluator の違いと関係
上記の定義の観点から見ると、Interpolator と TypeEvaluator の役割は同じです。
違いを言わなければならないとすれば、新しいアニメーション メカニズムが 2 つの「責任」を限定することです。名前からわかるように、一方は時間値を管理します (Interpolator は TimeInterpolator のインターフェイスを実装します)。 )、チューブタイプの値。
Interpolator の float getInterpolation(floatfraction) の呼び出し元は @input を [0, 1.0] に制限しているため、エントリ パラメーターは 1 つだけです。このメソッドの機能は、アニメーションの現在の進行状況を別の値にマッピングすることであり、これは「改ざん」と表現できるため、「補間改ざん」という関数名は非常に適切です。
TypeEvaluator の T Evaluator(floatfraction, T startValue, T endValue) は、アニメーションの初期値、最終値、および
改ざんされた 再生の進行状況に基づいて アニメーション プロセス値 なので、「evaluate」という関数の名前も非常に適切です。
詳細については、http://li2.me/2016/01/android-animation-interpolator.html を参照してください。
よろめいた adj. 驚いた。 LayoutAnimationController はコンテナのレイアウト アニメーションを実装するために使用されます。コンテナ内のサブビュー アニメーションは同じですが、開始時間が異なります。したがって、ここでの staggered は「千鳥状」を意味するはずです。
その他の単語やフレーズ
これはワイ・グオレンが具体的に言及したものです: 中国人は「遊び」という言葉をいつも間違って使います、ははは、説明しましょう。
関連ブログ記事
by
weiyi.li li2.me weiyi.just2@gmail.com
2016-01-28 ~ 2016-02-01
転載は禁止されています
英語の文書を読むことを翻訳の仕事だと考えていないプログラマーは料理が上手ではありません