棚の上のAndroidのアニメーション(パート1.基本アニメーション)

みなさんこんにちは!

今日は、Androidのアニメーションについて少しお話したいと思います。 誰にとっても明らかな事実は、アニメーションがアプリケーションを装飾できるということです。 しかし、私は彼らがもっともっとできると信じています。 まず、優れたアニメーションは、控えめなグラフィックでも、アプリケーションをまったく新しいレベルに引き上げることができます。 2つ目は、ユーザーと通信するための追加のツールです。これにより、注意を集中したり、アプリケーションの仕組みを提案したりできます。しかし、これは別の大きなトピックです。

今日は、アニメーションを作成するためのツールについて説明します。 残念ながら、Androidには何かをアニメートする方法がたくさんあり、最初は混乱するのが非常に簡単です。 最も一般的な分類を提供し、ドキュメントへのリンクのみを残すようにします。 チュートリアルはたくさんあります。 この記事が私の頭の中の棚にすべてを置き、必要に応じてアニメーションを作成し、最も適切な方法を選択するのに役立つことを願っています。

パート1.基本的なアニメーション
パート2.複雑なアニメーション
パート3.「低レベル」アニメーション
パート4.遷移アニメーション
パート5.アニメーションを操作するためのライブラリ

パート1.基本的なアニメーション


1.フレームごと


画像

世界で最初のアニメーションがそのように作成されたと思いますが、この機能はまだAndroidで利用できます。

必要なのは、各フレームへのリンクを含むxmlを作成することだけです。

<?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="true"> <item android:drawable="@drawable/explosion_1" android:duration="15" /> <item android:drawable="@drawable/explosion_2" android:duration="15" /> <item android:drawable="@drawable/explosion_3" android:duration="15" /> ... </animation-list> 

アニメーションを開始します(以下、すべての例はKotlinで提供されます)。
 val animation = image.drawable as AnimationDrawable animation.start() 

•アプリケーション:

複雑なアニメーショングラフィックス。サイズは小さく、外部エディターで準備されています。

•利点:

複雑なエフェクトを実現する機能

•欠点:

高いリソース消費。その結果、OutOfMemoryを取得する機能を備えたアプリケーションへの非常に高価なインポート。 何らかの理由で多数のフレームを表示する必要がある場合、メモリに画像を徐々にロードして実装を作成する必要があります。 しかし、そうしなければならない場合、おそらくビデオに頼る方が簡単でしょうか?

2.オブジェクトのプロパティのアニメーション(別名プロパティアニメーター)


画像

数ピクセルを横に移動するか、透明度を変更して互いに非常に類似した100万フレームを生成する必要がない場合、Animatorが助けになります。 実際、これを使用すると、オブジェクトのプロパティをアニメーション化できます。

基本抽象クラスはアニメーターと呼ばれ、いくつかの子孫があります。これは私たちにとって重要です。

ValueAnimator-任意のプロパティをアニメーション化できます
ObjectAnimator-ValueAnimatorを継承し、Viewプロパティをアニメーション化するためのシンプルなインターフェイスを備えています。
ViewPropertyAnimator-ビューをアニメーション化するための別の便利なインターフェイスを提供します。 Animatorから継承されず、View :: animate()メソッドで使用されます

上記のアニメーションは、コードのように記述できます。

 val animationX = ObjectAnimator.ofFloat(card, "scaleX", 1F) val animationY = ObjectAnimator.ofFloat(card, "scaleY", 1F) val set = AnimatorSet() set.play(animationX) .with(animationY) set.duration = DURATION set.interpolator = DecelerateInterpolator() set.start() 

XMLで( animator/open_animator.xml ):

 <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="together"> <objectAnimator android:duration="250" android:propertyName="scaleX" android:valueTo="1" android:valueType="floatType" android:interpolator="@android:anim/decelerate_interpolator"/> <objectAnimator android:duration="250" android:propertyName="scaleY" android:valueTo="1" android:valueType="floatType" android:interpolator="@android:anim/decelerate_interpolator"/> </set> 

 val set = AnimatorInflater.loadAnimator(context, R.animator.open_animator) as AnimatorSet set.setTarget(card) set.start() 

ビューステート間の遷移のアニメーションを記述することもできます。これにより、任意のビューのステート間のアニメーション化された遷移を簡単に作成できます。 ビューステートが変更されると、XMLで記述されたアニメーションが自動的に開始されます。
animator/state_animator.xml

 <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_enabled="true"> <set android:ordering="together"> <objectAnimator android:duration="250" android:interpolator="@android:anim/decelerate_interpolator" android:propertyName="scaleX" android:valueTo="1" android:valueType="floatType"/> <objectAnimator android:duration="250" android:interpolator="@android:anim/decelerate_interpolator" android:propertyName="scaleY" android:valueTo="1" android:valueType="floatType"/> </set> </item> <item android:state_enabled="false"> <set android:ordering="together"> <objectAnimator android:duration="250" android:interpolator="@android:anim/accelerate_interpolator" android:propertyName="scaleX" android:valueTo="0" android:valueType="floatType"/> <objectAnimator android:duration="250" android:interpolator="@android:anim/accelerate_interpolator" android:propertyName="scaleY" android:valueTo="0" android:valueType="floatType"/> </set> </item> </selector> 

 <View ... android:stateListAnimator="@animator/state_animator"> </View> 


•アプリケーション:

Viewオブジェクトとそのパラメーターのアニメーション
その他のパラメーターのアニメーション

•利点:

絶対に普遍的

•欠点:

ある程度リソースを消費します。

3.ビューアニメーション(別名ビューアニメーション)


Animatorの前は、Androidにはアニメーションしかありませんでした。 主な欠点は、ビューのビューのみをアニメーション化し、実際にそのプロパティを変更しなかったことです。 したがって、要素の動きをアニメーション化する場合は、アニメーションの最後に、そのプロパティも変更する必要があります。 多少複雑なアニメーションが必要な場合や、アニメーション時にクリックをキャッチする必要がある場合、何らかの方法でこのアプローチはあまり便利ではありません。

アニメーションはコードのように実行できます:

 val anim = ScaleAnimation(0F, 1F, 0F, 1F, 0F, card.measuredHeight.toFloat()) anim.duration = DURATION anim.interpolator = DecelerateInterpolator() anim.fillAfter = true card.startAnimation(anim) 

XMLと同様(構文はAnimatorのxmlとは異なることに注意してください):
anim/open_animation.xml

 <?xml version="1.0" encoding="utf-8"?> <scale xmlns:android="http://schemas.android.com/apk/res/android" android:duration="250" android:fillAfter="true" android:fromXScale="0" android:fromYScale="0" android:interpolator="@android:anim/decelerate_interpolator" android:pivotX="0" android:pivotY="100%" android:toXScale="1" android:toYScale="1"/> 

 val animation = AnimationUtils.loadAnimation(context, R.anim.open_animation) card.startAnimation(animation) 


•アプリケーション:

APIがAnimatorの使用を許可しない場合。

•利点:

利用できません

•欠点:

廃止されたAPI。ビューのみを変更します。

4.ベクトルリソースのアニメーション(別名AnimatedVectorDrawable)


画像

私の意見では、Androidアニメーションで最も興味深い部分です。 比較的小さな力で複雑で興味深い効果を実現できます。 Androidのアイコン変換はそのようにして行われます。

VectorDrawableは、Path要素とGroup要素で構成されます。 アニメーションの作成は、これらの要素への動きを登録することになります。 上の写真のAndroidのコードは次のようになります。

たくさんのコード
drawable/hello_android.xml
 <?xml version="1.0" encoding="utf-8"?> <animated-selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/enabled" android:drawable="@drawable/hello_android_enabled" android:state_enabled="true"/> <item android:id="@+id/disabled" android:drawable="@drawable/hello_android_disabled"/> <transition android:drawable="@drawable/hello_android_waving" android:fromId="@id/enabled" android:toId="@id/disabled"/> <transition android:drawable="@drawable/hello_android_stay_calm" android:fromId="@id/disabled" android:toId="@id/enabled"/> </animated-selector> 

drawable/hello_android_enabled.xml
 <vector xmlns:android="http://schemas.android.com/apk/res/android" android:name="vector" android:width="32dp" android:height="32dp" android:viewportWidth="32" android:viewportHeight="32"> <path android:name="path_1" android:pathData="M 15 13 L 14 13 L 14 12 L 15 12 M 10 13 L 9 13 L 9 12 L 10 12 M 15.53 10.16 L 16.84 8.85 C 17.03 8.66 17.03 8.34 16.84 8.14 C 16.64 7.95 16.32 7.95 16.13 8.14 L 14.65 9.62 C 13.85 9.23 12.95 9 12 9 C 11.04 9 10.14 9.23 9.34 9.63 L 7.85 8.14 C 7.66 7.95 7.34 7.95 7.15 8.14 C 6.95 8.34 6.95 8.66 7.15 8.85 L 8.46 10.16 C 6.97 11.26 6 13 6 15 L 18 15 C 18 13 17 11.25 15.53 10.16 M 3.5 16 C 2.672 16 2 16.672 2 17.5 L 2 24.5 C 2 25.328 2.672 26 3.5 26 C 4.328 26 5 25.328 5 24.5 L 5 17.5 C 5 16.672 4.328 16 3.5 16 M 6 26 C 6 26.552 6.448 27 7 27 L 8 27 L 8 30.5 C 8 31.328 8.672 32 9.5 32 C 10.328 32 11 31.328 11 30.5 L 11 27 L 13 27 L 13 30.5 C 13 31.328 13.672 32 14.5 32 C 15.328 32 16 31.328 16 30.5 L 16 27 L 17 27 C 17.552 27 18 26.552 18 26 L 18 16 L 6 16 L 6 26 Z" android:fillColor="#000000"/> <group android:name="group" android:rotation="-160" android:pivotX="20.5" android:pivotY="17"> <path android:name="path" android:pathData="M 20.5 16 C 19.672 16 19 16.672 19 17.5 L 19 24.5 C 19 25.328 19.672 26 20.5 26 C 21.328 26 22 25.328 22 24.5 L 22 17.5 C 22 16.672 21.328 16 20.5 16" android:fillColor="#000"/> </group> </vector> 

drawable/hello_android_disabled.xml

 <vector xmlns:android="http://schemas.android.com/apk/res/android" android:name="vector" android:width="32dp" android:height="32dp" android:viewportWidth="32" android:viewportHeight="32"> <path android:name="path_1" android:pathData="M 15 13 L 14 13 L 14 12 L 15 12 M 10 13 L 9 13 L 9 12 L 10 12 M 15.53 10.16 L 16.84 8.85 C 17.03 8.66 17.03 8.34 16.84 8.14 C 16.64 7.95 16.32 7.95 16.13 8.14 L 14.65 9.62 C 13.85 9.23 12.95 9 12 9 C 11.04 9 10.14 9.23 9.34 9.63 L 7.85 8.14 C 7.66 7.95 7.34 7.95 7.15 8.14 C 6.95 8.34 6.95 8.66 7.15 8.85 L 8.46 10.16 C 6.97 11.26 6 13 6 15 L 18 15 C 18 13 17 11.25 15.53 10.16 M 3.5 16 C 2.672 16 2 16.672 2 17.5 L 2 24.5 C 2 25.328 2.672 26 3.5 26 C 4.328 26 5 25.328 5 24.5 L 5 17.5 C 5 16.672 4.328 16 3.5 16 M 6 26 C 6 26.552 6.448 27 7 27 L 8 27 L 8 30.5 C 8 31.328 8.672 32 9.5 32 C 10.328 32 11 31.328 11 30.5 L 11 27 L 13 27 L 13 30.5 C 13 31.328 13.672 32 14.5 32 C 15.328 32 16 31.328 16 30.5 L 16 27 L 17 27 C 17.552 27 18 26.552 18 26 L 18 16 L 6 16 L 6 26 Z" android:fillColor="#000000"/> <group android:name="group" android:pivotX="20.5" android:pivotY="17"> <path android:name="path" android:pathData="M 20.5 16 C 19.672 16 19 16.672 19 17.5 L 19 24.5 C 19 25.328 19.672 26 20.5 26 C 21.328 26 22 25.328 22 24.5 L 22 17.5 C 22 16.672 21.328 16 20.5 16" android:fillColor="#000"/> </group> </vector> 

drawable/hello_android_waving.xml

 <animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"> <aapt:attr name="android:drawable"> <vector android:name="vector" android:width="32dp" android:height="32dp" android:viewportWidth="32" android:viewportHeight="32"> <path android:name="path_1" android:pathData="M 15 13 L 14 13 L 14 12 L 15 12 M 10 13 L 9 13 L 9 12 L 10 12 M 15.53 10.16 L 16.84 8.85 C 17.03 8.66 17.03 8.34 16.84 8.14 C 16.64 7.95 16.32 7.95 16.13 8.14 L 14.65 9.62 C 13.85 9.23 12.95 9 12 9 C 11.04 9 10.14 9.23 9.34 9.63 L 7.85 8.14 C 7.66 7.95 7.34 7.95 7.15 8.14 C 6.95 8.34 6.95 8.66 7.15 8.85 L 8.46 10.16 C 6.97 11.26 6 13 6 15 L 18 15 C 18 13 17 11.25 15.53 10.16 M 3.5 16 C 2.672 16 2 16.672 2 17.5 L 2 24.5 C 2 25.328 2.672 26 3.5 26 C 4.328 26 5 25.328 5 24.5 L 5 17.5 C 5 16.672 4.328 16 3.5 16 M 6 26 C 6 26.552 6.448 27 7 27 L 8 27 L 8 30.5 C 8 31.328 8.672 32 9.5 32 C 10.328 32 11 31.328 11 30.5 L 11 27 L 13 27 L 13 30.5 C 13 31.328 13.672 32 14.5 32 C 15.328 32 16 31.328 16 30.5 L 16 27 L 17 27 C 17.552 27 18 26.552 18 26 L 18 16 L 6 16 L 6 26 Z" android:fillColor="#000000"/> <group android:name="group" android:pivotX="20.5" android:pivotY="17"> <path android:name="path" android:pathData="M 20.5 16 C 19.672 16 19 16.672 19 17.5 L 19 24.5 C 19 25.328 19.672 26 20.5 26 C 21.328 26 22 25.328 22 24.5 L 22 17.5 C 22 16.672 21.328 16 20.5 16" android:fillColor="#000"/> </group> </vector> </aapt:attr> <target android:name="group"> <aapt:attr name="android:animation"> <set> <objectAnimator android:propertyName="rotation" android:duration="300" android:valueFrom="0" android:valueTo="-170" android:valueType="floatType" android:interpolator="@android:anim/decelerate_interpolator"/> <objectAnimator android:propertyName="rotation" android:startOffset="300" android:duration="200" android:valueFrom="-170" android:valueTo="-160" android:valueType="floatType" android:interpolator="@android:interpolator/fast_out_slow_in"/> <objectAnimator android:propertyName="rotation" android:startOffset="500" android:duration="200" android:valueFrom="-160" android:valueTo="-170" android:valueType="floatType" android:interpolator="@android:interpolator/fast_out_slow_in"/> <objectAnimator android:propertyName="rotation" android:startOffset="700" android:duration="200" android:valueFrom="-170" android:valueTo="-160" android:valueType="floatType" android:interpolator="@android:interpolator/fast_out_slow_in"/> </set> </aapt:attr> </target> </animated-vector> 

drawable/hello_android_stay_calm.xml

 <animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"> <aapt:attr name="android:drawable"> <vector android:name="vector" android:width="32dp" android:height="32dp" android:viewportHeight="32" android:viewportWidth="32"> <path android:fillColor="#000000" android:pathData="M 15 13 L 14 13 L 14 12 L 15 12 M 10 13 L 9 13 L 9 12 L 10 12 M 15.53 10.16 L 16.84 8.85 C 17.03 8.66 17.03 8.34 16.84 8.14 C 16.64 7.95 16.32 7.95 16.13 8.14 L 14.65 9.62 C 13.85 9.23 12.95 9 12 9 C 11.04 9 10.14 9.23 9.34 9.63 L 7.85 8.14 C 7.66 7.95 7.34 7.95 7.15 8.14 C 6.95 8.34 6.95 8.66 7.15 8.85 L 8.46 10.16 C 6.97 11.26 6 13 6 15 L 18 15 C 18 13 17 11.25 15.53 10.16 M 3.5 16 C 2.672 16 2 16.672 2 17.5 L 2 24.5 C 2 25.328 2.672 26 3.5 26 C 4.328 26 5 25.328 5 24.5 L 5 17.5 C 5 16.672 4.328 16 3.5 16 M 6 26 C 6 26.552 6.448 27 7 27 L 8 27 L 8 30.5 C 8 31.328 8.672 32 9.5 32 C 10.328 32 11 31.328 11 30.5 L 11 27 L 13 27 L 13 30.5 C 13 31.328 13.672 32 14.5 32 C 15.328 32 16 31.328 16 30.5 L 16 27 L 17 27 C 17.552 27 18 26.552 18 26 L 18 16 L 6 16 L 6 26 Z"/> <group android:name="arm" android:pivotX="20.5" android:pivotY="17" android:rotation="-160"> <path android:name="path" android:fillColor="#000" android:pathData="M 20.5 16 C 19.672 16 19 16.672 19 17.5 L 19 24.5 C 19 25.328 19.672 26 20.5 26 C 21.328 26 22 25.328 22 24.5 L 22 17.5 C 22 16.672 21.328 16 20.5 16"/> </group> </vector> </aapt:attr> <target android:name="arm"> <aapt:attr name="android:animation"> <set> <objectAnimator android:duration="300" android:interpolator="@android:anim/decelerate_interpolator" android:propertyName="rotation" android:valueFrom="-160" android:valueTo="0" android:valueType="floatType"/> </set> </aapt:attr> </target> </animated-vector> 


XMLを手動で記述しないようにするには、 オンラインツールを使用できます

API 25から、ベクトルアニメーションはRenderThreadでレンダリングされるため、UIスレッドに何かを読み込んだとしても(そうしないのですか?)、アニメーションは引き続きスムーズに再生されます。

•アプリケーション:

アイコン
アニメーション効果

•利点:

性能

•欠点:

アニメーションの時点を手動で制御する方法はありません(つまり、実際にはsetCurrentTimeのようなメソッドはありません)

ここですべての例を見て勉強できます

Source: https://habr.com/ru/post/J347918/


All Articles