techium

このブログは何かに追われないと頑張れない人たちが週一更新をノルマに技術情報を発信するブログです。もし何か調査して欲しい内容がありましたら、@kobashinG or @muchiki0226 までいただけますと気が向いたら調査するかもしれません。

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行で様々なアニメーションを簡単に記述することができます。

アニメーションはめんどくさいという認識がかなり安らぎました!