Androidのアニメーションに関するチュートリアル
この記事はraywenderlich.comのページを翻訳したものです。
以前にAndroidのアニメーションの実装がややこしい話しをしましたので今後案件で雑に設計しないように自分のメモがわりに記載しました。
iOSエンジニアから見たAndroidアプリ開発とiOSアプリ開発の違いについて説明します
もちろん、誤字脱字があればご連絡頂ければと思います。
前置き
アニメーション要素のないモバイルエクスペリエンスは想像しにくいです。それらは楽しくて美しく、ユーザーを適切にアプリの使い方を導くだけでなく、スクリーンを生き生きとさせる力を持っています。
画面上のオブジェクトを生き生きとさせるビルドアニメーションの実装は、最初は航空宇宙工学のように見えるかもしれませんが、恐れることはありません! Androidには、比較的簡単にアニメーションを作成するのに役立つツールがあります。
このチュートリアルでは、ロケットを使って宇宙へ(おそらく月に)ドッグを打ち上げ、安全に地面に戻って戻っていく実装を通して、いくつかの重要なアニメーションツールに慣れ親しむことを学びます。
これらのDogeアニメーションを作成することで、以下のことを学ぶことができます:
-
プロパティアニメーション
の作成 – 最も便利で簡単なAndroidアニメーション - AndroidのViewを移動して消す
- シーケンス内のアニメーションを結合するか、同時にアニメーションを開始する
- 繰り返しと反転のアニメーション
- アニメーションのタイミングを調整する
- ロケット科学者の一人になる
前提条件: このAndroidチュートリアルはすべてアニメーションに関するものなので、AndroidプログラミングとKotlin、Android Studio、XMLレイアウトの知識が必要です。Androidが初めての方は、最初にAndroid開発パート1をチェックしてみてください。
多くのアニメーション。 そのようなコード。 高速ロケット。
はじめに
アニメーションはなんて楽しい話題でしょうか! ビルドアニメーションを習得する最善の方法は、コードで手を汚すことです。(笑)
まず、Rocket Launcher Starterをダウンロードします。それをAndroid Studio 3.0 Beta 7以降のバージョンで読み込んでから、あなたの端末で実行してください。あなたはすぐに実行するための必要なものをすべてを見つけるでしょう。
アプリをビルドするとデバイス上で、実装するすべてのアニメーションのリストが表示されます。
リストの項目をクリックします。
Dogeとロケットの2つの静的画像が表示され、Dogeは乗る準備ができています。 現時点では、すべての画面は同じで、まだアニメーションはありません。
プロパティアニメーションはどのように機能するか
最初のアニメーションの作業をする前に、理論の道を歩き、魔法の背後にある論理を明確にしておきましょう。
ロケットの打ち上げを画面の下端から上端までアニメーションする必要があり、ロケットが正確に50ミリ秒で作れると想像してください。
時間の経過と共にロケットの位置がどのように変化するかをプロットしたグラフがあります:
上のアニメーションは滑らかで連続的です。 しかし、スマートフォンはデジタルであり、離散値で動作します。 時間はアニメーションのために継続的には流れません。 それは小さなステップで進歩します。
アニメーションは、フレームとも呼ばれる多くの静止画で構成され、指定された時間で1つずつ表示されます。 今回のコンセプトは最初の漫画と同じですが、レンダリングは少し異なります。
フレーム間の経過時間はフレームリフレッシュ遅延と呼ばれ、プロパティアニメーションのデフォルトでは10ミリ秒です。
ここではアニメーションが映画の初期の時代とは違っています:ロケットが一定速度で動いていることがわかっているときは、いつでもロケットの位置を計算できます。
下に示す6つのアニメーションフレームが表示されます。 注意として
- アニメーションの初めに、ロケットは画面の下端にあります。
- ロケットの位置はすべてのフレームでそのパスの同じ部分だけ上に移動する
- アニメーションが終わるまでに、ロケットはスクリーンの上端にあります。
TL / DR:与えられたフレームを描くとき、継続時間とフレームリフレッシュレートに基づいてロケットの位置を計算します。
幸いにも、ValueAnimatorがあなたのためにやってくれているので、すべての計算を手動で行う必要はありません。
アニメーションを設定するには、アニメーション化されるプロパティの開始値と終了値、および継続時間を指定するだけです。 また、コールするリスナーを追加する必要があります。これにより、各フレームのロケットの新しい位置が設定されます。
Time Interpolators(タイムインターポレータ)
あなたはおそらく、ロケットがアニメーション全体で一定のスピードで動くことに気づいたでしょう – それほど現実的ではありません。 マテリアルデザインは、より自然な方法で動作しながら、ユーザーの注意を引く生き生きとしたアニメーションを作成することを奨励します。
Androidのアニメーションフレームワークでは、Time Interpolatorsを使用しています。 ValueAnimator
はTime Interpolatorインターフェイスを実装するオブジェクトを持っています。 時間補間器は、時間の経過とともにアニメーション値がどのように変化するかを決定します。
最も単純なケースでは、経時的な位置変化のグラフをもう一度見直してください。(Linear Interpolator)
このLinearInterpolator
が時間の変化にどのように応答するかは次のとおりです。
時間に依存して、ロケットの位置は一定の速度で変化するか直線的に変化します。
アニメーションは、非線形補間器を有することもできる。 このような例の1つがAccelerateInterpolator
です。
これは入力値を2乗することでロケットがゆっくりと加速し、素早く加速するようにします。実際のロケットのように!
それはあなたが始めるために知っておく必要がある理論のほとんどがすべてです。今のところはね。。。
Your First Animation
あなたが移動する前に、プロジェクトに慣れるためにしばらく時間をかけてください。com.raywenderlich.rocketlauncher.animationactivities
パッケージには、BaseAnimationActivityと、このクラスを拡張するその他すべてのアクティビティが含まれています。
res/layoutフォルダ内のactivity_base_animation.xmlファイルを開きます。
ルートには、画像付きのImageView
の2つのインスタンスが含まれているFrameLayout
があります.1つはrocket.png、もう1つはdoge.pngです。どちらもAndroid:layout_gravity
にbottom|center_horizontal
を設定して、画像を画面の下の中央に描写します。
このチュートリアルでは、多くのファイルナビゲーションを行います。 Android Studioでこれらの便利なショートカットを使用して、物事間を簡単に移動させることができます。
LinuxとWindowsの場合は、Ctrl + Shift + N
で、Macの場合は、command + shift + O
で任意のファイルに移動します
LinuxとWindowsの場合は、Ctrl + N
でMacの場合には、コマンド+ O
を使用してKotlinクラスに移動する
BaseAnimationActivity
は、このアプリケーション内の他のすべてのアニメーションアクティビティのスーパークラスです。
BaseAnimationActivity.ktを開き、内部を見てください。 一番上には、すべてのアニメーションアクティビティからアクセス可能なView
メンバ変数があります。
-
rocket
はロケットのイメージを持つビューです -
doge
はDogeの画像を含むビューです -
frameLayout
は、rocket
とdoge
の両方を含むFrameLayoutです。 -
screenHeight
は、便宜上、画面の高さと同じになります
rocket
とdoge
はどちらもImageView
の一種ですが、プロパティアニメーションはすべてのAndroidビューで動作するため、それぞれをView
として宣言しています。 ビューはまた、レイアウトが膨張され、例えば、ActivityのonCreate()
のような適切なライフサイクルイベントにバインドされるまでnullであるため、lateinit値として宣言されます。
onCreate()
を見てコードを観察してください:
// 1
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_base_animation)
// 2
rocket = findViewById(R.id.rocket)
doge = findViewById(R.id.doge)
frameLayout = findViewById(R.id.container)
// 3
frameLayout.setOnClickListener { onStartAnimation() }
ここでは、このコードで何が起こっているのかというと
- スーパークラスで
onCreate()
を呼び出し、レイアウトファイルでSetContentView(...)
を呼び出します。 - XMLレイアウトを適用し、
FrameLayout
、rocket
、およびdoge
を対応するビューにバインドします。 -
FrameLayout
のonClickListener
を設定します。 - ユーザーが画面をタップするたびに
onStartAnimation()
を呼び出します。 これは、BaseAnimationActivity
を拡張する各Activityによって定義されるabstractメソッドです。
この基本コードは、このチュートリアルで編集するすべてのアクティビティで共有されます。 これであなたはそれに精通しているので、今こそカスタマイズを開始するときです!
Launch the Rocket
あなたがロケット打ち上げを開始しない限り、Dogeはどこにも行かないので、それはとても簡単で始めるには最高のアニメーションです。 ロケット科学はとてもシンプルだと誰が思ったでしょうか?
LaunchRocketValueAnimatorAnimationActivity.ktを開き、次のコードをonStartAnimation()
の本文に追加します。
//1
val valueAnimator = ValueAnimator.ofFloat(0f, -screenHeight)
//2
valueAnimator.addUpdateListener {
val value = it.animatedValue as Float
rocket.translationY = value
}
//5
valueAnimator.interpolator = LinearInterpolator()
valueAnimator.duration = BaseAnimationActivity.Companion.DEFAULT_ANIMATION_DURATION
//6
valueAnimator.start()
- 静的メソッド
forFloat
を呼び出して、ValueAnimator
のインスタンスを作成します。時間の経過とともにアニメーションオブジェクトの指定されたプロパティに適用される浮動小数点数を受け入れます。 この場合、値は0f
で始まり、-screenHeight
で終わります。 Androidはスクリーン座標を左上のコーナーで開始するので、ロケットのY変換は0から画面の高さの負に変化します。つまり、下から上に移動します。 -
addUpdateListener()
を呼び出し、リスナーを渡します。ValueAnimator
は、アニメーション化された値の更新ごとにこのリスナーを呼び出します。デフォルトの遅延は10msです。 - アニメーターから現在の値を取得し、floatにキャストします。
ofFloat
でValueAnimator
を作成したため、現在の値の型はfloat
です。 - そのtranslationYの値を設定してロケットの位置を変更します。
- アニメータの時間とinterpolatorを設定します。
- アニメーションを開始します。
ビルドして実行します。 リストからLaunch a Rocketを選択します。 新しい画面が表示されます。 それをタップしましょう!
それは楽しいよね? :]Dogeが残っていることを心配しないでください – 彼は少し後に月に彼のロケット船をキャッチしにいきます。
Put a Spin on It
ロケットに少し回転動作を与えるのはどうですか? RotateRocketAnimationActivity.ktを開き、次のコードをonStartAnimation()
に追加します。
// 1
val valueAnimator = ValueAnimator.ofFloat(0f, 360f)
valueAnimator.addUpdateListener {
val value = it.animatedValue as Float
// 2
rocket.rotation = value
}
valueAnimator.interpolator = LinearInterpolator()
valueAnimator.duration = BaseAnimationActivity.Companion.DEFAULT_ANIMATION_DURATION
valueAnimator.start()
違いを見つけることができますか?
1. valueAnimator
の値を0f
から360f
に変更すると、ロケットは完全な回転になります。 0f
から180f
に変更することでUターンエフェクトを作成することができます。
2. translationY
を設定する代わりに、ロケットのrotation(回転)
を設定するのは、それが変更する必要があるためです。
ビルドして、実行し、Spin a rocketを選択します。 新しい画面が表示されたらタップしましょう。
Accelerate the Launch
AccelerateRocketAnimationActivity.ktを開き、あなたの旧友onStartAnimation()
に次のコードを追加してください:
// 1
val valueAnimator = ValueAnimator.ofFloat(0f, -screenHeight)
valueAnimator.addUpdateListener {
val value = it.animatedValue as Float
rocket.translationY = value
}
// 2 - Here set your favorite interpolator
valueAnimator.interpolator = AccelerateInterpolator(1.5f)
valueAnimator.duration = BaseAnimationActivity.DEFAULT_ANIMATION_DURATION
// 3
valueAnimator.start()
上記のコードは、LaunchRocketValueAnimationActivity.ktのonStartAnimation()
と同じですが例外が1行です。valueAnimator.interpolator
の設定に使用されたインターポレータの部分です。
ビルドして実行してみましょう。リスト内のAccelerate a rocketを選択します。 新しいスクリーンをタップすると、ロケットの動きを確認できます。
再び、私たちは、貧しいDogeが月にロケットを捕まえていないことが分かります…貧しいfella。 そこにハングアップ、バディ!
AccelerateInterpolatorを使用しているので、離陸後にロケットが加速しているのを確認する必要があります。 あなたが望むならば、interpolatorsで遊んでも構いません。 私はここに座って待ちます。 約束しましょう。
Which Properties Can You Animate?
これまではView
の位置と回転だけをアニメーション化しましたが、ValueAnimator
は、その値を使って何をしているかは気にしません。
ValueAnimator
に、次のいずれかのタイプを使用して値をアニメーションさせるように指示できます。
-
ofFloat
でValueAnimator
インスタンスを作成する場合はfloat - intの場合はint
-
ofObject
は、float
またはint
が十分でない場合に使用されます。色をアニメーション化するためによく使用されます
View
の任意のプロパティをアニメーションさせることもできます。 いくつかの例があります:
-
scaleX
およびscaleY
– ビューをx軸またはy軸で個別に拡大/縮小させることができます。または、両方を同じ値で呼び出して、ビューのサイズをアニメーションできます。 -
translationX
およびtranslationY
– これらを使用すると、ビューの画面上の位置を変更できます。 -
alpha
– ビューの透明度をアニメーションさせる。0
は完全に透明であり、1
は完全に不透明である。 -
rotation
– 画面上のビューを回転させます。 引数は度であり、360
は完全な時計回りの回転を意味します。 負の値を指定することもできます。たとえば、-90
は反時計回りの1/4回転を意味します。 -
rotationX
とrotationY
–rotation
と同じですが、x軸とy軸に沿っています。 これらのプロパティを使用すると、3Dで回転できます。 -
backgroundColor
– 色を設定します。 整数の引数は、Androidの定数Color.YELLOW
、Color.BLUE
と同じ色を指定する必要があります。
ObjectAnimator
ValueAnimator
のサブクラスであるObjectAnimator
を見てください。 1つのオブジェクトの1つのプロパティだけをアニメーション化する必要がある場合、ObjectAnimator
は新しいベストフレンドになるかもしれません。
ValueAnimator
では、リスナーを設定して値で何かを行う必要がありますが、ObjectAnimator
はこれらのビットをほぼ自動的に処理できます。
LaunchRocketObjectAnimatorAnimationActivity.ktクラスに移動し、次のコードを入力します。
// 1
val objectAnimator = ObjectAnimator.ofFloat(rocket, "translationY", 0f, -screenHeight)
// 2
objectAnimator.duration = BaseAnimationActivity.Companion.DEFAULT_ANIMATION_DURATION
objectAnimator.start()
ここでやっていることは、
-
ObjectAnimator
のインスタンスを作成する(ValueAnimator
の場合のように)。ただし、前者は2つのパラメータをさらに必要とする。 -
rocket
はアニメーションのオブジェクトです。 - オブジェクトには、変更するプロパティの名前に対応するプロパティが必要です(この例では「
translationY
」です)。rocket
は、Base Javaクラスで、setTranslationY()
を使用してアクセス可能なセッターを持つView
クラスのオブジェクトであるため、これを行うことができます。 - アニメーションの継続時間を設定して開始します。
プロジェクトを実行します。 リストでLaunch a rocket (ObjectAnimator)を選択します。 画面をタップします。
ロケットはValueAnimator
と同じように動作しますが、コードは少なくなります。
ObjectAnimator
には制限があります.2つのオブジェクトを同時にアニメーション化することはできません。 この問題を回避するには、ObjectAnimator
のインスタンスを2つ作成します。
ObjectAnimator
またはValueAnimator
を使用することを決定した場合の使用例とコーディング量を考慮してください。
Animating Color
ユースケースについて言えば、アニメーションの色を考慮する必要があります。 ofFloat()
もinInt()
も、あなたのアニメーターを構築することも、色で良い結果を得ることもできません。 あなたはArgbEvaluator
を使う方が良いです。
ColorAnimationActivity.ktを開き、このコードをonStartAnimation()
に入れてください。
//1
val objectAnimator = ObjectAnimator.ofObject(
frameLayout,
"backgroundColor",
ArgbEvaluator(),
ContextCompat.getColor(this, R.color.background_from),
ContextCompat.getColor(this, R.color.background_to)
)
// 2
objectAnimator.repeatCount = 1
objectAnimator.repeatMode = ValueAnimator.REVERSE
// 3
objectAnimator.duration = BaseAnimationActivity.Companion.DEFAULT_ANIMATION_DURATION
objectAnimator.start()
上記のコードでは、
-
ObjectAnimator.ofObject()
を呼び出し、それに以下の引数を与えます。
-
frameLayout
– アニメーション化されるプロパティを持つオブジェクト -
backgroundColor
– アニメーション化するプロパティ -
ArgbEvaluator()
– 2つの異なるARGB(アルファ、赤、緑、青)のカラー値を補間する方法を指定する追加の引数 - Start and end color values(カラー値の開始と終了) – ここでは、
ComtextCompat.getColor()
を使用して、colors.xml
で指定されたカスタムなカラーのColor Resouce IDを取得します。
- オブジェクトの
repeatCount
値を設定して、アニメーションが繰り返される回数を設定します。 次に、そのrepeatMode
を設定して、アニメーションが最後に達したときの動作を定義します。 もうすぐこれについてもっと詳しく説明します! - アニメーション時間を設定し、アニメーションを開始します。
ビルドして実行します。 Background colorの項目を選択し、画面をタップします。
それは素晴らしいです! Hey、あなたはこれをかなり素早くつかまえています。 それはバタフライで滑らかな背景色の変化です。
Combining Animations
ビューをアニメーション化するのはすごく素晴らしいですが、これまでは一度に1つのプロパティと1つのオブジェクトしか変更していません。 アニメーションはそれほど制限的である必要はありません。
では、Dogeを月に送る時です!
AnimatorSet
を使用すると、複数のアニメーションを一緒に、または順番に再生できます。 最初のアニメーターをplay()
に渡します。これは、Animator
オブジェクトを引数として受け取りビルダーを返します。
次に、そのBuilderで次のメソッドを呼び出すことができます。これらのメソッドはすべて、Animator
を引数として受け入れます。
-
with()
–play()
で指定した最初のものと同時に引数として渡されたAnimator
を再生するためのもの -
before()
– 前に再生する -
after()
– 後に再生する
これらのような一連の呼び出しを作成できます。
エディタでLaunchAndSpinAnimatorSetAnimatorActivity.ktを開き、次のコードをonStartAnimation()
に挿入します。
// 1
val positionAnimator = ValueAnimator.ofFloat(0f, -screenHeight)
// 2
positionAnimator.addUpdateListener {
val value = it.animatedValue as Float
rocket.translationY = value
}
// 3
val rotationAnimator = ObjectAnimator.ofFloat(rocket, "rotation", 0f, 180f)
// 4
val animatorSet = AnimatorSet()
// 5
animatorSet.play(positionAnimator).with(rotationAnimator)
// 6
animatorSet.duration = BaseAnimationActivity.Companion.DEFAULT_ANIMATION_DURATION
animatorSet.start()
このブロックであなたがやっていることは次のとおりです。
1. 新しいValueAnimator
を作成します。
2. ロケットの位置を更新するValueAnimatorにAnimatorUpdateListener
を付け加えます。
3. ロケットの回転を更新する2番目のアニメーターであるObjectAnimator
を作成します。
4. AnimatorSet
の新しいインスタンスを作成します。
5. rotationAnimator
と一緒にpositionAnimator
を実行するように指定します。
6. 典型的なアニメーションと同様に、アニメーションの時間を設定してstart()
を呼び出します。
もう一度ビルドして実行してください。 Launch and spin(AnimatorSet)を選択します。 画面をタップします。
Dogeはこれで物理学の法則に反します。
同じオブジェクトのいくつかのプロパティを簡単にアニメーション化するための素晴らしいツールがあります。 このツールというのは、、、
ViewPropertyAnimator
ViewPropertyAnimatorを使用するアニメーションのコードの最大の特徴の1つは、書き込みと読み込みが容易だということです。
LaunchAndSpinViewPropertyAnimatorAnimationActivity.ktを開き、次の呼び出しをonStartAnimation()
に追加します。
(ViewPropertyAnimator)
rocket.animate()
.translationY(-screenHeight)
.rotationBy(360f)
.setDuration(BaseAnimationActivity.Companion.DEFAULT_ANIMATION_DURATION)
.start()
ここでは、animate()
はViewPropertyAnimator
のインスタンスを返し、呼び出しをチェインさせることができます(メソッドチェイン)。
ビルドして実行し、起動してLaunch and spin (ViewPropertyAnimator)を選択すると、前のセクションと同じアニメーションが表示されます。
このセクションのコードを、前のセクションで実装したAnimatorSet
のコードスニペットと比較してください。
(AnimatorSet)
val positionAnimator = ValueAnimator.ofFloat(0f, -screenHeight)
positionAnimator.addUpdateListener {
val value = it.animatedValue as Float
rocket?.translationY = value
}
val rotationAnimator = ObjectAnimator.ofFloat(rocket, "rotation", 0f, 180f)
val animatorSet = AnimatorSet()
animatorSet.play(positionAnimator).with(rotationAnimator)
animatorSet.duration = BaseAnimationActivity.Companion.DEFAULT_ANIMATION_DURATION
animatorSet.start()
ViewPropertyAnimator
は、複数の同時アニメーションに対してより良いパフォーマンスを提供します。 無効化された呼び出しを最適化するので、いくつかのプロパティに対しては1回しか発生しません。それぞれのアニメーション化されたプロパティとは対照的に、独立した独自の無効化を引き起こします。
Animating the Same Property of Two Objects
ValueAnimator
の優れた機能は、アニメーション化された値を再利用して、好きなだけ多くのオブジェクトに適用できることです。
FlyWithDogeAnimationActivity.ktを開き、次のコードをonStartAnimation()
に入れてテストしてください。
//1
val positionAnimator = ValueAnimator.ofFloat(0f, -screenHeight)
positionAnimator.addUpdateListener {
val value = it.animatedValue as Float
rocket.translationY = value
doge.translationY = value
}
//2
val rotationAnimator = ValueAnimator.ofFloat(0f, 360f)
rotationAnimator.addUpdateListener {
val value = it.animatedValue as Float
doge.rotation = value
}
//3
val animatorSet = AnimatorSet()
animatorSet.play(positionAnimator).with(rotationAnimator)
animatorSet.duration = BaseAnimationActivity.Companion.DEFAULT_ANIMATION_DURATION
animatorSet.start()
上記のコードでは、3つのアニメーターを作成しました。
-
positionAnimator
–rocket
とdoge
の位置を変更する -
rotationAnimator
– Dogeを回転させる -
animatorSet
– 最初の2つのアニメーターを結合する
最初のアニメーターで2つのオブジェクトの変換を一度に設定することに注意してください。
アプリケーションを実行し、Doe behind behind(2つのオブジェクトのアニメーション)を選択しないでください。 今何をすべきかわかるはずです。 そう、月へ!
Animation Listeners
アニメーションとは通常、特定のアクションが発生したか、あるいは発生することを意味します。 通常何が起こっても、通たいていはあなたのファンシーなアニメーションの終わりが来ます。
あなたはそれを観察することはできませんが、ロケットが停止し、アニメーションが終了するとスクリーンから離れたままであることがわかります。 着陸を計画していない場合、またはアクティビティを終了する予定がない場合は、この特定のビューを削除してリソースを節約できます。
AnimatorListener
– 次のイベントが発生したときにアニメータから通知を受け取ります。
-
onAnimationStart()
– アニメーションの開始時に呼び出されます。 -
onAnimationEnd()
– アニメーションの終了時に呼び出されます。 -
onAnimationRepeat()
– アニメーションが繰り返される場合に呼び出されます。 -
onAnimationCancel()
– アニメーションがキャンセルされた場合に呼び出されます。
WithListenerAnimationActivity.ktを開き、次のコードをonStartAnimation()
に追加します。
//1
val animator = ValueAnimator.ofFloat(0f, -screenHeight)
animator.addUpdateListener {
val value = it.animatedValue as Float
rocket.translationY = value
doge.translationY = value
}
// 2
animator.addListener(object : Animator.AnimatorListener {
override fun onAnimationStart(animation: Animator) {
// 3
Toast.makeText(applicationContext, "Doge took off", Toast.LENGTH_SHORT)
.show()
}
override fun onAnimationEnd(animation: Animator) {
// 4
Toast.makeText(applicationContext, "Doge is on the moon", Toast.LENGTH_SHORT)
.show()
finish()
}
override fun onAnimationCancel(animation: Animator) {}
override fun onAnimationRepeat(animation: Animator) {}
})
// 5
animator.duration = 5000L
animator.start()
上記のコードの構造は、リスナー部分を除いて、前のセクションと同じように見えるはずです。 ここでしていることは、
- アニメーターを作成して設定します。
ValueAnimator
を使用して、2つのオブジェクトの位置を同時に変更します。1つのObjectAnimator
で同じことをすることはできません。 -
AnimatorListener
を追加します。 - アニメーション開始時にトーストメッセージを表示する
- 終了時には別のトーストを表示させます。
- いつものようにアニメーションを開始する
アプリを実行します。 Animation eventsを選択します。 画面をタップします。 メッセージを見てください!
start()
を呼び出す前に、コールチェーンにsetListener
を追加することによって、ViewPropertyAnimator
にリスナーを追加することもできます。
rocket.animate().setListener(object : Animator.AnimatorListener {
// Your action
})
あるいは、
Animate()
の後にwithStartAction(Runnable)
とwithEndAction(Runnable)
を呼び出すことで、ビューの開始アクションと終了アクションを設定できます。 これらのアクションを持つAnimatorListener
と同等です。
Animation Options
アニメーションは、単に停止したり進んだりするワントリックのポニーではありません。 例えば、ループ、逆転、特定の時間実行するなどなど。
Androidでは、次の方法を使用してアニメーションを調整できます。
-
repeatCount
– 最初の実行後にアニメーションを繰り返す回数を指定します。 -
repeatMode
– このアニメーションが最後に達したときに何をすべきかを定義します。 -
duration
– アニメーションの合計時間を指定します。
FlyThereAndBackAnimationActivity.ktを開き、次のコードをonStartAnimation()
に追加します。
// 1
val animator = ValueAnimator.ofFloat(0f, -screenHeight)
animator.addUpdateListener {
val value = it.animatedValue as Float
rocket.translationY = value
doge.translationY = value
}
// 2
animator.repeatMode = ValueAnimator.REVERSE
// 3
animator.repeatCount = 3
// 4
animator.duration = 500L
animator.start()
ここでは、
- いつものようにアニメーターを作成する。
-
repeatMode
を次のいずれかに設定できます。
-
RESTART
– 最初からアニメーションを再開します。 -
REVERSE
– 反復ごとにアニメーションの方向を反転します。
この場合、ロケットを離陸させてから始動したのと同じ位置に戻る必要があるため、これをREVERSE
に設定します。 ちょうどSpaceXのように!
- それを2回することを除きます。
- 通常どおり、アニメーション時間を設定し、アニメーションを開始します。
なぜ3番目のセクションで3回のrepeat countを指定するのですか? それぞれの上下運動は2回の繰り返しを消費するので、Dogeを2度地球に戻すには3回が必要です.1回は最初に着陸し、もう2回は着陸して再び着陸します。Dogeが跳ね返るのをどれくらいしたいですか? それで遊んでみてください!
アプリを実行します。 リスト内のFly there and back (Animation options)を選択します。新しい画面が開きます。画面をタップします。
あなたはロケットがバッタのようにジャンプするのを見てください! それを取る、Elon Musk。
Declaring Animations in XML
あなたはこのチュートリアルの最も重要な部分を作りました。 この最後のセクションでは、一度宣言してどこでも使用する方法を学びます。そうです。あなたのアニメーションを無断で再利用できるようになります。
XMLでアニメーションを定義することで、コードベース全体でアニメーションを再利用できます。
XMLでのアニメーションの定義は、ビューレイアウトの作成と似ています。
スタータープロジェクトには、res/animatorにjump_and_blink.xmlというアニメーションXMLがあります。 エディタでファイルを開くと、これが表示されます。
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together">
</set>
次のXMLタグを利用できます
-
set
–AnimatorSet
と同じ -
animator
–ValueAnimator
と同じ -
objectAnimator
– あなたは正しく推測するでしょう。ObjectAnimator
の略です。
XMLでAnimatorSet
を使用する場合は、レイアウトXMLファイル内のViewGroup
オブジェクト(RelativeLayout
やLinearLayout
など)内にView
オブジェクトをネストする方法と同じように、その内部にValueAnimator
オブジェクトとObjectAnimator
オブジェクトをネストします。
jump_and_blink.xmlの内容を次のコードに置き換えます。
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together">
<objectAnimator
android:propertyName="alpha"
android:duration="1000"
android:repeatCount="1"
android:repeatMode="reverse"
android:interpolator="@android:interpolator/linear"
android:valueFrom="1.0"
android:valueTo="0.0"
android:valueType="floatType"/>
<objectAnimator
android:propertyName="translationY"
android:duration="1000"
android:repeatCount="1"
android:repeatMode="reverse"
android:interpolator="@android:interpolator/bounce"
android:valueFrom="0"
android:valueTo="-500"
android:valueType="floatType"/>
</set>
ここで、ルート要素のset
タグを宣言します。 そのordering
属性は、together
でもsequential
でもかまいません。 デフォルトではtogether
になっていますが、明確にするために指定することをお勧めします。set
タグには2つの子XMLタグがあり、それぞれはobjectAnimator
です。
objectAnimator
の次の属性を見てください。
-
android:valueFrom
とandroid:valueTo
–ObjectAnimator
のインスタンスを作成したときのように開始値と終了値を指定します。 -
android:valueType
– 値の型。floatType
またはintType
のいずれか -
android:propertyName
–set
部分なしでアニメーションするプロパティ -
android:duration
– アニメーションの長さ -
android:repeatCount
–setRepeatCount
と同じです -
android:repeatMode
–setRepeatMode
と同じです -
android:interpolator
– interpolatorを指定します。 通常は@android:interpolator/
で始まります。 これを入力すると、Android Studioはオートコンプリートオプションの下で利用可能なすべてのinterpolatorを表示します。 - ここであなたのターゲットオブジェクトを指定することはできませんが、後でKotlinで行うことができます
最後のブロックでは、objectAnimator
の2つのインスタンスをAnimatorSet
に追加し、それらは一緒に再生されます。 今、それらを使う時です。
XmlAnimationActivity.ktに移動し、次のコードをonStartAnimation()
に追加します。
// 1
val rocketAnimatorSet = AnimatorInflater.loadAnimator(this, R.animator.jump_and_blink) as AnimatorSet
// 2
rocketAnimatorSet.setTarget(rocket)
// 3
val dogeAnimatorSet = AnimatorInflater.loadAnimator(this, R.animator.jump_and_blink) as AnimatorSet
// 4
dogeAnimatorSet.setTarget(doge)
// 5
val bothAnimatorSet = AnimatorSet()
bothAnimatorSet.playTogether(rocketAnimatorSet, dogeAnimatorSet)
// 6
bothAnimatorSet.duration = BaseAnimationActivity.Companion.DEFAULT_ANIMATION_DURATION
bothAnimatorSet.start()
上記のコードでは、いくつかのことをしています。
- まず、通常はビューレイアウトをinflateするのと同じように、
R.animator.jump_and_blink
ファイルからAnimatorSet
をロードします - 次に、ロードした
Animator
をターゲットとしてロケットに設定します - もう一度同じファイルからAnimatorを読み込みます。
- dogeオブジェクトのためにすすぎと繰り返し
- 今度は、3つ目の
AnimatorSet
を作成し、最初の2つを同時に再生するように設定します - root animatorのアニメーション時間を設定して開始する
- すごい! 少しだけ休む
ビルドして実行します。 一覧からJump and blink (Animations in XML)を選択します。 あなたの手仕事を見るにはタップしてください。
Dogeがジャンプして消えて、また地面に安全に帰ってくるのを見てください。
あとがき
これで本セクションの解説を終わります。
Happy Halloween!!!