Android - Value AnimatorでImageViewのサイズ変更をする

Animatorを使ってImageViewを操作することがあったのですが、ちょっと調べたので残しておきたいと思います。

Animator

AndroidにはAnimationクラスのほかに、Animatorクラスが存在します。
AnimatorはAndroid 3.0から導入されたAPIですが、特徴としてはAnimationが描画だけを行うのに対してAnimatorは対象となるView(Object)の持つパラメータ自体を実際に変更させるAPIになります。

Animatorについては下記ブログが詳しいです。

AndroidでもiPhoneに負けないようなアニメーションを実装してみよう - Yahoo! JAPAN Tech Blog

ImageView のサイズをAnimatorで変更してみる

上記記事にもあるように、ObjectAnimatorは便利なのですが例えばImageViewのheightやwidthを変更することができません。

下記のようにObjectAnimator.ofFloat()の引数に渡す文字列はターゲットとなるオブジェクト(ここではImageView)のSetter/Getterも指定できるようなのですが、 これは内部的にリフレクションでImageView.getYなどを使って値を直接変更しているためのようです。

なので、LayoutParamsで設定するwidthやheightは操作できないようです。

//Y position
ObjectAnimator positionObjectAnimator = ObjectAnimator.ofFloat(imageView, "y", imageView.getY(), 100);
positionObjectAnimator.setDuration(ANIMATION_DURATION);
positionObjectAnimator.setInterpolator(new DecelerateInterpolator(ANIMATION_FACTOR));
positionObjectAnimator.start();

このケースではValueAnimatorを使います。下記に参考になる解答があります。

android - ObjectAnimator animate LinearLayout width - Stack Overflow

ValueAnimatorは、その名のとおり特定の値を指定した数値から、 指定した数値まで、設定したDurationやInterpolatorに従ってアニメーション数値を算出してくれるAnimatorです。

//size
int currentHeight = imageView.getLayoutParams().height;
int targetHeight = 100;
ValueAnimator heightValueAnimator = ValueAnimator.ofInt(currentHeight, targetHeight);
heightValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator valueAnimator) {
        int val = (Integer) valueAnimator.getAnimatedValue();
        ViewGroup.LayoutParams layoutParams = imageView.getLayoutParams();
        layoutParams.height = val;
        imageView.setLayoutParams(layoutParams);
    }
});
heightValueAnimator.setDuration(ANIMATION_DURATION);
heightValueAnimator.setInterpolator(new DecelerateInterpolator(ANIMATION_FACTOR));
heightValueAnimator.start();

addUpdateListenerでCallbackを登録し、その中で操作したい値の更新を記述しておきます。 これによって、上の例のようにImageViewのheightを操作するなどの柔軟なアニメーションが可能になります。