izuki
9/12/2017 - 5:44 AM

Android ImageViewのアニメーション(Interpolator(処理を補完)を使ってポヨンとさせる)

Android ImageViewのアニメーション(Interpolator(処理を補完)を使ってポヨンとさせる)

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.animation.Animation;
import android.view.animation.Interpolator;
import android.view.animation.ScaleAnimation;
import android.widget.ImageView;

public class MainActivity extends AppCompatActivity {
    private String TAG = "LOG!";

    ImageView imageView;
    // final はC言語で言う所のconstみたいなもんだからつけられないよ
    Animation pathDown;
    Animation pathCancel;
    Animation pathUp;
    private boolean canceled = false;

    // res/anim/にファイルを定義していたらフィールド定義の時点で以下の様に書けます。
    // 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);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initAnime();
            imageView = (ImageView)findViewById(R.id.imageView);
        imageView.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {

                if(event.getAction() == MotionEvent.ACTION_DOWN){
                    Log.d(TAG, "down!");
                    imageView.startAnimation(pathDown);
                }else if(event.getAction() == MotionEvent.ACTION_UP){
                    Log.d(TAG, "up!");
                    if(canceled){
                        canceled = false;
                    }else{
                        imageView.startAnimation(pathUp);
                    }

                }
                return true;   // true にしとかないと UP が呼ばれない
            }
        });
    }

    private void initAnime(){
        // pathDown
        pathDown = new ScaleAnimation(
                1.0f, 0.85f,   // Xスケールサイズ(開始時→終了時)
                1.0f, 0.85f,   // Yスケールサイズ(開始時→終了時)
                ScaleAnimation.RELATIVE_TO_SELF, 0.5f,  // X座標のタイプ、X座標(0.5fがview中央値)
                ScaleAnimation.RELATIVE_TO_SELF, 0.5f); // Y座標のタイプ、Y座標(0.5fがview中央値)
        // 0.1秒かけてアニメーションする(ms)
        pathDown.setDuration(100);
        // アニメーション終了時の表示状態を維持する
        pathDown.setFillEnabled(true);
        pathDown.setFillAfter(true);

        // pathCancel
        pathCancel = new ScaleAnimation(
                0.85f, 1.0f,   // Xスケールサイズ(開始時→終了時)
                0.85f, 1.0f,   // Yスケールサイズ(開始時→終了時)
                ScaleAnimation.RELATIVE_TO_SELF, 0.5f,  // X座標のタイプ、X座標(0.5fがview中央値)
                ScaleAnimation.RELATIVE_TO_SELF, 0.5f); // Y座標のタイプ、Y座標(0.5fがview中央値)

        // 0.1秒かけてアニメーションする(ms)
        pathCancel.setDuration(100);
        // アニメーション終了時の表示状態を維持する
        pathCancel.setFillEnabled(true);
        pathCancel.setFillAfter(true);


        // pathUp
        pathUp = new ScaleAnimation(
                0.85f, 1.0f,   // Xスケールサイズ(開始時→終了時)
                0.85f, 1.0f,   // Yスケールサイズ(開始時→終了時)
                ScaleAnimation.RELATIVE_TO_SELF, 0.5f,  // X座標のタイプ、X座標(0.5fがview中央値)
                ScaleAnimation.RELATIVE_TO_SELF, 0.5f); // Y座標のタイプ、Y座標(0.5fがview中央値)

        // 0.48秒かけてアニメーションする(ms)
        pathUp.setDuration(480);
        // アニメーション終了時の表示状態を維持する
        pathUp.setFillEnabled(true);
        pathUp.setFillAfter(false);
        // Interpolitorの読み込み(とても大事)
        pathUp.setInterpolator(new CustomInterpolator());
    }
}

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;
        }
    }
}