[Android Studio] ボタンを押した時のアニメーションを作ってみる

#はじめに
Android Studioのボタンには、押した時の動きも最初からついている。
でも、自分なりにボタンを押した時の動きを作ってみたいということで、そのやり方をメモ。

#やりたいこと
ボタンを押したときにサイズを小さくし、ボタンを放し時にサイズを元に戻すようなアニメーションを作りたい。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/278251/f3866633-e911-f905-cccd-8e9fc76ac76d.png)



#カスタムボタンクラスを作る
まず、ボタンを押した際の動きを記述するため、ボタンクラスを継承させたカスタムボタンクラスを作ります。
背景色とテキストは適当です。

```java:CustomButton.java

public class CustomButton extends Button {

    public CustomButton(Context context, AttributeSet attr) {
        super(context, attr);

        this.setBackgroundColor(Color.RED);
        this.setText("カスタムボタン");
    }

}

```

#setPressedメソッドをオーバーライドする
ボタンクラスにはsetPresseedメソッドがあり、このメソッドをオーバーライドすることでボタンをクリック時の処理を設定することができます。

```java:CustomButton.java
    /* ボタンプレスイベント */
    @Override
    public void setPressed(boolean pressed) {
        if (pressed) {
            /* 押してる時 */
        } else {
            /* 放した時 */
        }

        super.setPressed(pressed);
    }
```

setPressedメソッドの引数にはboolean型のpressedというのがあります。
ボタンを押した時にtrue、放したときにfalseが入るので、if文を使って押したときの処理、放したときの処理を記述できるようにしてます。

#ScaleAnimationクラスを使ってアニメーション内容を記述する
今回は、ボタンを押した際にサイズを変えるだけなのでScaleAnimationを使います。

### ScaleAnimationクラスとは
Android Developers : https://developer.android.com/reference/android/view/animation/ScaleAnimation
リファレンスを見てみるとScaleAnimationクラスは「オブジェクトのスケールを制御するアニメーション」と書いてあります。
つまり、ボタンやビューの拡大、縮小などサイズに関するアニメーションができるクラスのようです。

###ScaleAnimationクラスの使い方
※ScaleAnimationの設定はxmlでも記述できるようですが、私自身xmlが苦手なのでjavaで記述させていただきます

ScaleAnimationクラスは以下のように宣言する

```java
ScaleAnimation scaleAnimation = new ScaleAnimation(
        fromX, toX, fromY, toY,
        pivotXType, pivotXvalue,
        pivotYType, pivotYvalue
);
scaleAnimation.setDuration(150);
scaleAnimation.setRepeatCount(0);
scaleAnimation.setFillAfter(true);
this.startAnimation(scaleAnimation);
```

| 値 | 説明 |
|:-----------------|:------------------|
| fromX (float)         | アニメーション開始時の横の長さの倍率         |
| toX (float)           | アニメーション終了時の横の長さの倍率         |
| fromY (float)         | アニメーション開始時の縦の長さの倍率         |
| toY (float)           | アニメーション終了時の縦の長さの倍率         |
| pivotXType (int)      | pivotXValueの解釈方法                     |
| pivotXValue (float)   | オブジェクトの拡大縮小のX軸の中心座標     |
| pivotYType  (int)     | pivotYValueの解釈方法                     |
| pivotYValue (float)   | オブジェクトの拡大縮小のY軸の中心座標     |

|メソッド名|説明|
|:----------|-----------|
|setDuration|アニメーションの時間。ミリ秒で記述|
|setRepeatCount|アニメーションの繰り返し回数|
|setFillAfter|アニメーション終了時のサイズをそのままビューに反映させるか、させないか|
|startAnimation|アニメーション開始|


pivotXType, pivotYTypeは3種類のなかから選ぶ。

- **Animation.ABSOLUTE** : 左上から見たpixel絶対値。pivotX(Y)Valueは120のようにpixel数で記述する
- **Animation.RELATIVE_TO_SELF** : 自分のサイズの割合。pivotX(Y)Valueは0.0f ~ 1.0fの割合で記述する
- **Animation.RELATIVE_TO_PARENT** : 親サイズの割合。pivotX(Y)Valueは0.0f ~ 1.0fの割合で記述する

例えば、下記のコードはボタンの中心を軸に0.5倍に縮小します。

```java
ScaleAnimation scaleAnimation = new ScaleAnimation(
        1.0f, 0.5f, 1.0f, 0.5f,
        Animation.RELATIVE_TO_SELF, 0.5f,
        Animation.RELATIVE_TO_SELF, 0.5f
);
```

![image2.png](https://qiita-image-store.s3.amazonaws.com/0/278251/128f4859-4604-a71b-4116-0d3cacb967ec.png)

では、ScaleAnimationクラスを使ってボタンを押した時の拡大縮小の設定を記述します。

```java:CustomButton.java
/* ボタンプレスイベント */
@Override
public void setPressed(boolean pressed) {
    if (pressed) {
        /* 押してる時 */
        ScaleAnimation scaleAnimation = new ScaleAnimation(
                1.0f, 0.6f / 1.0f, 1.0f, 0.6f / 1.0f,
                Animation.RELATIVE_TO_SELF, 0.5f,
                Animation.RELATIVE_TO_SELF, 0.5f
        );
        scaleAnimation.setDuration(150);
        scaleAnimation.setRepeatCount(0);
        scaleAnimation.setFillAfter(true);

        this.startAnimation(scaleAnimation);
    } else {
        /* 放した時 */
        ScaleAnimation scaleAnimation = new ScaleAnimation(
                0.6f / 1.0f, 1.0f, 0.6f / 1.0f, 1.0f,
                Animation.RELATIVE_TO_SELF, 0.5f,
                Animation.RELATIVE_TO_SELF, 0.5f
        );
        scaleAnimation.setDuration(150);
        scaleAnimation.setRepeatCount(0);
        scaleAnimation.setFillAfter(true);

        this.startAnimation(scaleAnimation);
    }

    super.setPressed(pressed);
}
```

#実行結果
![ezgif-1-f3a0e2a78b.gif](https://qiita-image-store.s3.amazonaws.com/0/278251/3f3613ea-bcf4-7558-8c79-3a7deaa6484d.gif)

#参考文献
Android 簡単にボタンに"押した感"を出す - Qiita : https://qiita.com/hsakurai2/items/a4356bd7bf0aac26b0cd
[Android] ScaleAnimation 拡大・縮小アニメーション : https://akira-watson.com/android/scale-animation.html