LoginSignup
61
58

More than 5 years have passed since last update.

ついつい押したくなる気持ちいい動きをするボタンを作る

Posted at

はじめに

私が今まで触った中で一番気持ちよかったボタンは、Moves(下記リンク)の中で使われている円形のボタンなのですが、これと似たような動きをするボタンを作ってみました。
https://play.google.com/store/apps/details?id=com.protogeo.moves

Untitled3.gif

ポイント

ポイントは、ボタンを離した時のポヨヨンと動く感じです。カスタムした Interpolator を使ったのですが、結果的にこんな感じになりました。はい、見たくないですね。

CustomInterpolator.java
public class CustomInterpolator implements Interpolator {

    public CustomInterpolator() {
    }

    public float getInterpolation(float input) {
        if (input < 0.4) {
            return (float) ((Math.cos((2.5 * input + 1) * Math.PI) / 2.0f) + 0.5f) * 2f;
        } else if (input < 0.8) {
            return (float) ((Math.cos((2.5 * input + 1) * Math.PI) / 2.0f) + 0.5f) * 1.5f + 0.5f;
        } else {
            return (float) ((Math.cos((2.5 * input + 1) * Math.PI) / 2.0f) + 0.5f) * 1f + 0.5f;
        }
    }
}

このへんを参考にして作りました。
http://cogitolearning.co.uk/?p=1078
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.0.0_r1/android/view/animation/AccelerateDecelerateInterpolator.java#AccelerateDecelerateInterpolator

グラフはこんな感じです。ちなみにこのグラフは、Mac の Grapher というアプリを使って描画しました。

graph.png

コード

実際に使うなら Activity や Fragment には書きたくないですね。適当なクラスを作って、クリックイベントのコールバック用インタフェースを用意すればといいと思います。

もう少しいい方法があるんじゃないかなぁという気がしなくもないです。

SampleActivity.java
final Button button = (Button) findViewById(R.id.button);
final Animation pathDown = AnimationUtils.loadAnimation(this, R.anim.path_down);
final Animation pathCancel = AnimationUtils.loadAnimation(this, R.anim.path_cancel);
final Animation pathUp = AnimationUtils.loadAnimation(this, R.anim.path_up);
pathUp.setInterpolator(new CustomInterpolator());

button.setOnTouchListener(new View.OnTouchListener() {

    private boolean cancelled = false;

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {

            case MotionEvent.ACTION_DOWN:
                button.startAnimation(pathDown);
                break;

            case MotionEvent.ACTION_MOVE:
                if (!cancelled) {
                    // ボタンからフォーカスが外れた場合
                    if (event.getX() < 0
                            || v.getWidth() < event.getX()
                            || event.getY() < 0
                            || v.getHeight() < event.getY()) {
                        cancelled = true;
                        button.startAnimation(pathCancel);
                    }
                }
                break;

            case MotionEvent.ACTION_UP:
                if (cancelled) {
                    cancelled = false;
                } else {
                    button.startAnimation(pathUp);
                    // クリックイベントの処理
                }
                break;
        }

        return true;
    }
});
anim/path_down.xml
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="100"
    android:fillAfter="true"
    android:fromXScale="1.0"
    android:fromYScale="1.0"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toXScale="0.85"
    android:toYScale="0.85" />
anim/path_cancel.xml
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="100"
    android:fillAfter="true"
    android:fromXScale="0.85"
    android:fromYScale="0.85"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toXScale="1"
    android:toYScale="1" />
anim/path_up.xml
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="480"
    android:fillAfter="false"
    android:fromXScale="0.85"
    android:fromYScale="0.85"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toXScale="1"
    android:toYScale="1" />
61
58
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
61
58