Property Animationを使って画像を回転させながら移動していく途中で、停止・再開させるには AnimatorPauseListener を使うことで可能です。更に AnimatorListenerAdapter を設定しておくと便利です。
2021.2.1
Property Animation
からの続きです。Property AnimationはAnimationの中間値を実際に作っているので、そのあるタイミングで停止させることも可能です。これはAnimationを見せているだけのView Animationではできないことです。
AnimatorPauseListener
AnimatorListener
を実装してリスナーをObjectに設定すると、開始、キャンセル、終了、リピートがコールバックされますが、一時停止とその後の再開はAnimatorPauseListenerを使わないとできません。
設定はAnimatorListenerとほとんど同様ですが、pauseとresumeにはその時の状態を確認してpause()とresume()を実行させます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
public class MainActivity extends AppCompatActivity implements Animator.AnimatorPauseListener{ ObjectAnimator objectAnimator; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... // 一時停止 Button buttonPause = findViewById(R.id.button_pause); buttonPause.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (objectAnimator != null) { if (objectAnimator.isRunning()) { objectAnimator.pause(); } } } }); // 再開 Button buttonResumed = findViewById(R.id.button_resumed); buttonResumed.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (objectAnimator != null) { if (objectAnimator.isPaused()) { objectAnimator.resume(); } } } }); ... objectAnimator.addPauseListener(this); ... } // アニメーション中断 @Override public void onAnimationPause(Animator animation) { Log.d("debug","onAnimationPause()"); } // アニメーション中断からの再開 @Override public void onAnimationResume(Animator animation) { Log.d("debug","onAnimationResume()"); } } |
AnimatorListenerAdapter
AnimatorPauseListenerを実装するだけでは、開始や終了のコールバックを受け取れないので、2つのInterfaceを追加実装することも可能です。ただ、AnimatorListenerAdapterを使うと簡単に処理することができます。
AnimatorListenerAdapterはデフォルトでAnimatorListenerAdapterとAnimatorPauseListenerそれぞれ空のメソッドを実装してくれます。あとはどれか必要なコールバックの処理を記述するだけで済みます。
また、addListener と addPauseListener のどちらでも設定でき機能します。
サンプルコード
MainActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
//package your.package.name; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.animation.Animator; import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.util.Log; import android.widget.Button; import android.widget.ImageView; import android.animation.AnimatorListenerAdapter; public class MainActivity extends AppCompatActivity { private ImageView imageView; private ObjectAnimator objectAnimator; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button buttonStart = findViewById(R.id.button_start); imageView = findViewById(R.id.image_view); imageView.setImageResource(R.drawable.bag); // Animation 開始 buttonStart.setOnClickListener(v -> setAnimetion()); // 一時停止 Button buttonPause = findViewById(R.id.button_pause); buttonPause.setOnClickListener(v -> { if (objectAnimator != null) { if (objectAnimator.isRunning()) { objectAnimator.pause(); } } }); // 再開 Button buttonResumed = findViewById(R.id.button_resumed); buttonResumed.setOnClickListener(v -> { if (objectAnimator != null) { if (objectAnimator.isPaused()) { objectAnimator.resume(); } } }); } private void setAnimetion() { // PropertyValuesHolderを使ってX軸方向移動範囲のpropertyを保持 PropertyValuesHolder vhX = PropertyValuesHolder.ofFloat( "translationX", 0.0f, 600.0f); // PropertyValuesHolderを使ってY軸方向移動範囲のpropertyを保持 PropertyValuesHolder vhY = PropertyValuesHolder.ofFloat( "translationY", 0.0f, 1200.0f); // PropertyValuesHolderを使って回転範囲のpropertyを保持 PropertyValuesHolder vhRotaion = PropertyValuesHolder.ofFloat( "rotation", 0.0f, 360.0f); // ObjectAnimatorにセットする objectAnimator = ObjectAnimator.ofPropertyValuesHolder( imageView, vhX, vhY, vhRotaion); // 再生時間を設定 3000msec=3sec objectAnimator.setDuration(3000); //objectAnimator.addListener(new AnimatorListenerAdapter() { objectAnimator.addPauseListener(new AnimatorListenerAdapter() { /* // アニメーション開始で呼ばれる @Override public void onAnimationStart(Animator animation) { Log.d("debug","onAnimationStart()"); } // アニメーションがキャンセルされると呼ばれる @Override public void onAnimationCancel(Animator animation) { Log.d("debug","onAnimationCancel()"); } // アニメーション終了時 @Override public void onAnimationEnd(Animator animation) { Log.d("debug","onAnimationEnd()"); } // 繰り返しでコールバックされる @Override public void onAnimationRepeat(Animator animation) { Log.d("debug","onAnimationRepeat()"); } */ // アニメーション中断 @Override public void onAnimationPause(Animator animation) { Log.d("debug", "onAnimationPause()"); } // アニメーション中断からの再開 @Override public void onAnimationResume(Animator animation) { Log.d("debug", "onAnimationResume()"); } }); // アニメーションを開始する objectAnimator.start(); } } |
activity_main.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="#db9" tools:context=".MainActivity"> <ImageView android:id="@+id/image_view" android:contentDescription="@string/description" android:layout_width="200dp" android:layout_height="200dp" /> <Button android:id="@+id/button_start" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="4dp" android:text="@string/start" /> <Button android:id="@+id/button_pause" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="4dp" android:text="@string/pause" /> <Button android:id="@+id/button_resumed" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="4dp" android:text="@string/resume"/> </LinearLayout> |
リソース
strings.xml
1 2 3 4 5 6 7 |
<resources> <string name="app_name">YourAppName</string> <string name="description">bag</string> <string name="start">Start</string> <string name="pause">Pause</string> <string name="resume">Resume</string> </resources> |
サンプル動画
関連ページ:
- android.view.animation
- Property Animation 画像が回転して落ちていくアニメーション
- AnimatorListenerAdapter によるAnimationの一時停止と再開くアニメーション
- frame-by-frame Animation でパラパラアニメーション
- TransitionDrawable クロスフェード animation
Reference:
Property Animation | Android Developers
AnimatorListenerAdapter | Android Developers