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