2012-10-31 1 views
7

私はProperty AnimationHardware Accelerationについて読んだことがありますが、アニメータークラスを使用する最も効率的な方法はまだ不明です。 (この質問のために、Honeycombの前にデバイスをサポートする必要はありませんので、アニメータクラスを使いたいと思います)。アニメータークラスを使用してビュー内の描画可能なものをアニメーション化する最適な方法は何ですか?

たとえば、私はビューを持っています。このビューには、私がフェードインしたいBitmapDrawableがあります。ビュー内には変更されない多くの要素もあります。

アニメーターでは、どのようなプロパティやオブジェクトを使用するのが最適でしょうか?ドロアブル? onDrawでビットマップを描画しているペイントですか?他に何か?

これは、どのようにしてハードウェアアクセラレーションで最も効率的に行うことができますか?これには、アニメーションの各ステップごとに無効化を呼び出す必要があるのでしょうか、または描画可能なもののみをアニメーション化し、残りのビューをアニメーションの各ステップで完全に再描画しない方法がありますか?

私は、ソフトウェアの中で完全に再描画する必要はないという最適なケースが残っていると思いますが、むしろハードウェアアクセラレーションは効率的に描画可能なものを消してしまいます。

推奨されるアプローチについてのご意見はありますか?

ありがとうございます!

+0

これは問題を引き起こしているので、これを尋ねていると思います。アニメーションはおそらくすべてを無効にしていますが、私たちにあなたが持っているビュー階層を表示すると、回避策が見つかるかもしれません。あなたがアニメ化しているものを指定してください。 –

+0

いいえ、まだ何も書いていない、私がする前にすべての情報を取得しようとしています。 :) – cottonBallPaws

+0

アニメーションが平均的なデバイスでうまくいくなら、私たちはいいです。ただし、ハードウェアアクセラレーションなどの一般的な拡張機能(常に利用可能なわけではない可能性があります)を行った後でさえ、目立つほど重い場合は、自分の解決策を見つける必要があります。たとえば、階層全体を無効にしている背景をアニメートする場合は、階層のスナップショットを作成し、背景のアニメーションを作成します。とにかく、おそらくハードウェアアクセラレーションとほとんどのデバイスでうまくいくので、努力をするかどうかは本質的にあなたの決定です。 (うまくいけば:) –

答えて

4

Object Property Animatorsを使用すると、基本的には、「N」が変更するプロパティである「Xミリ秒」ごとに「setN()」メソッドを繰り返し呼び出す数学関数に過ぎません。

アルファの場合に提供される例では、アニメーション化しているビューを再描画するには、どちらもinvalidate()を呼び出す必要があります。相違点は、をViewオブジェクトに呼び出すときです。invalidate()が呼び出されます。描画オブジェクトの描画に使用するPaintオブジェクトに対象オブジェクトを設定する場合は、をViewに呼び出して、新しいPaintパラメータで再描画する必要があります。

理想的には、できるだけ上位レベルの子にターゲットを設定したいので、再描画はアニメーション化するビューでのみ行われます。たとえば、ターゲットをルートビューに設定すると、ViewGroup内のすべての子に対してinvalidate()が呼び出され、ViewGroup内のすべての子に対してdraw()が呼び出されます。それをトップレベルImageViewに設定すると、ImageViewだけが再描画されます。

ハードウェアを最大限に活用するには、レイヤープロパティーを使用する必要があります。まず、アニメートする最上位の親ビューがどのようになるかを決定する必要があります。 Drawableだけを消したい場合は、DrawableまたはViewを含むでしょう。すべてを消したい場合は、それがルートビューになります。あなたがアニメートすることを決めたものは、一度に全体としてViewに適用されます。

Animatorを起動する直前に親ビューでsetLayerType()を使用してください。 View#LAYER_TYPE_HARDWAREに設定します。次に、AnimationListenerを設定し、アニメーターの完了時にレイヤータイプをView#LAYER_TYPE_SOFTWAREまたはView#LAYER_TYPE_NONEにリセットします。あなたがtranslateXプロパティを使用してmyParentViewを翻訳した場合

myParentView.setLayerType(View.LAYER_TYPE_HARDWARE, null); 
myObjectAnimator.addListener(new ViewAnimator.AnimatorListener() { 
    public void onAnimationEnd(Animator animation) { 
    myParentView.setLayerType(View.LAYER_TYPE_NONE); 
    } 
    public void onAnimationRepeat(Animator animation) { 
    } 
    public void onAnimationStart(Animator animation) { 
    } 
    public void onAnimationCancel(Animator animation) { 
    myParentView.setLayerType(View.LAYER_TYPE_NONE, null); 
    } 
} 
myObjectAnimator.start(); 

は、この場合、それは一つの面に層 myParentViewと、すべてのそれの子を配置します。それをハードウェアメモリに入れてください。ビュー全体を一度に翻訳します。完了したら、メモリから myParentViewを削除します。

EDIT:

最後の注意点、アルファは、CPUに大混乱を天下。ハーフアルファに何かがあり、それをビュー全体に翻訳すると、単にビューを翻訳するよりもレンダリングが難しくなります。それは控えめに使用してください。

1

おそらく、オリジナルのビューに新しいビュー(アニメーターのみを含む)をオーバーレイすることができます。新しいビューは透明に設定されます。

リセットすると元の表示なしで新しい表示が無効になります。

1

ご質問をお待ちしてから、standard documentにアクセスしてください。正しくinvalidate()の使い方を理解してください。第二に、異なる状況でアニメーションを扱うためのアンドロイドAPIによって既に提供されているさまざまな方法があります。

Here、あなたの疑問のほとんどがクリアされることを願っています。サブセクションとその関連ブログを参照してください。

希望すると、これが役立ちます。

関連する問題