ViewAnimatorを利用してアニメーションする
今回は、ViewAnimatorというOSSのライブラリを試してみました。
Androidのアニメーションはなんだかめんどくさいイメージがありましたが、ViewAnimatorを使うことでとても簡単にアニメーションを付与することができて素晴らしいです。
ということで今回は、本家のReadmeに沿ってViewAnimatorを試してみます。
準備
まずは恒例Gradleの設定です。
build.gradle(app)のdependenciesに以下を追記します。
compile 'com.github.florent37:viewanimator:1.0.3@aar' compile 'com.nineoldandroids:library:2.4.0'
これだけです。便利な世の中ですねぇ。
ImageViewとTextViewにAnimationを付与する
Dagger2の説明でも使用したサンプルの、画像とテキストViewの一部にアニメーションを適用してみます。
今回はとりあえずImageViewとTextViewに以下のようにアニメーションを付与してみます。
[MainActivity.java]
import com.github.florent37.viewanimator.AnimationListener; import com.github.florent37.viewanimator.ViewAnimator; public class MainActivity extends AppCompatActivity { private Hanter hanter; @Inject Weapon mWeapon; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final ActivityMainBinding binder = DataBindingUtil.setContentView(this, R.layout.activity_main); hanter = new Hanter("ハンタくん", "MAN"); binder.setHanter(hanter); binder.setImageUrl("http://uentseit.com/memoryuploader/icon.png"); binder.btnChangeGender.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { hanter.gender.set("WOMAN"); //hanter.setGender("WOMAN"); } }); DaggerEquipmentComponent.builder() .appModule(new AppModule(getApplication())).weaponModule(new WeaponModule()) .build().inject(this); // チャージアックスを装備 binder.btnEquipment.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { //mWeapon.equipment(); mWeapon.equipment(); } }); // 雪山Activityに遷移 binder.btnToField.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(getApplicationContext(), SnowMountain.class); startActivity(intent); } }); // アニメーションさせるView取得 TextView text = binder.txtHello; ImageView image = binder.imgSample; // ここからアニメーション ViewAnimator .animate(image) .translationX(-1000, 0) .alpha(0,1) .andAnimate(text) .dp() .translationX(-20, 0) .descelerate() .duration(2000) .thenAnimate(image) .scale(1f,0.5f,1f) .accelerate() .duration(1000) .start(); // 実行
ViewAnimatorはBuilderパターンを使って実装されてます。
アニメーションを付与したいViewのAnimationBuilderを取得し、取得したAnimationBuilderごとに対してアニメーションを連結していきます。
上記の例で使用しているメソッドは以下の表にまとめました。
メソッド名 | 概要 |
---|---|
animate | AnimationBuilderを取得 |
translationX | X方向への移動 |
andAnimate | 新たなAnimationBuilderを取得 |
dp() | 数値をdpとして扱う |
descelerate | アニメーションの速度を徐々に減速 |
duration | アニメーションする時間 |
thenAnimate | 新たなAnimationBuilderを取得。ただし直前のAnimation終了後に実行 |
scale | 拡大縮小 |
accelerate | アニメーションの速度を徐々に加速 |
start | アニメーションの実行 |
AnimatorBuilder取得時に複数のViewを指定することもできます。これで、同じアニメーションが別々のViewにそれぞれ適用され、同時に実行されます。
以下の例では、移動と透過のアニメーションをimageViewとTextViewに適用しています。
// 複数のViewに同じアニメーション ViewAnimator .animate(image,text) .translationX(-1000, 0) .alpha(0,1) .start();
幅と高さを変えるアニメーション
幅と高さを変更するには、Widthとheightメソッドを使います。
ViewAnimator .animate(image) .waitForHeight() .dp().width(100,200) .dp().height(50,100) .start();
waitForHeightメソッドを使うことで、View(ここではimage)の描画が行われるまでアニメーションの開始を我慢します。
アニメーションの開始時と終了時に処理を行う
ViewAnimatorでは、Listenerをセットすることでアニメーションの開始時と終了時のイベントを取得することができます。
[MainActivity.java]
@Override protected void onCreate(Bundle savedInstanceState) { (・・・略・・・) ViewAnimator .animate(image) .scale(0,1) .onStart(startListener) // アニメーション開始時に呼ばれる .onStop(stopListener) // アニメーションが止まったら呼ばれる .start(); } AnimationListener.Start startListener = new AnimationListener.Start(){ @Override public void onStart() { Toast.makeText(getApplicationContext(), "onStart", Toast.LENGTH_SHORT).show(); } }; AnimationListener.Stop stopListener = new AnimationListener.Stop(){ @Override public void onStop() { Toast.makeText(getApplicationContext(), "onStop", Toast.LENGTH_SHORT).show(); } };
自作アニメーション
ViewAnimatorを使ってアニメーションを自作することも可能です。
ViewAnimator .animate(text) .custom(new AnimationListener.Update<TextView>() { @Override public void update(TextView view, float value) { // 左にPaddingを入れてちょっとずつ右に移動 view.setPadding((int) (100 * value),0,0,0); } }, 0, 1) .custom(new AnimationListener.Update<TextView>() { @Override public void update(TextView view, float value) { // 背景色の透過をちょっとずつ濃くしていく view.setBackgroundColor(Color.YELLOW); view.setAlpha(value); } }, 0.0f, 1.0f) .start();
上記のようにすれば、TextViewが少しずつ右に移動しながら背景色の透過度が変化していきます。
以上のように、公式のサンプルを参考にいくつか動かしてみましたが、
「.」で繋ぐことでたった1行で様々なアニメーションを簡単に記述することができます。
アニメーションはめんどくさいという認識がかなり安らぎました!