API Demosに入っているBouncingBalls (http://goo.gl/HuQSf)を自分でも書いてみた。
ただし、勉強のため
・背景色は静的なものとし、AnimatorUpdateListenerによってinvalidateの処理を行うこととした。(オリジナルのBouncingBallsは背景色を変化させることで自動的にinvalidateの処理をおこなっている)
・オリジナルにあるShapeHolderクラスを使用しない。つまり、メインのBouncingBallsクラスの中で全て完結させる。また、ObjectAnimatorは使用せず、全てValueAnimatorで処理する。
という制限をつけて行った。
上手いコードにはなっていないが、とりあえずできたので貼りつけておく。
import java.util.ArrayList;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.widget.LinearLayout;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator.AnimatorUpdateListener;
public class BouncingBallsActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
((LinearLayout) findViewById(R.id.container)).addView(new MyView(this));
}
public class MyView extends View implements AnimatorUpdateListener {
int i = 0;
ArrayList<Integer> rgb = new ArrayList<Integer>();
ArrayList<AnimatorSet> animatorSet = new ArrayList<AnimatorSet>();
ArrayList<ValueAnimator> animLeft1 = new ArrayList<ValueAnimator>();
ArrayList<ValueAnimator> animTop1 = new ArrayList<ValueAnimator>();
ArrayList<ValueAnimator> animRight1 = new ArrayList<ValueAnimator>();
ArrayList<ValueAnimator> animBottom1 = new ArrayList<ValueAnimator>();
ArrayList<AnimatorSet> animatorSet1 = new ArrayList<AnimatorSet>();
ArrayList<ValueAnimator> animLeft2 = new ArrayList<ValueAnimator>();
ArrayList<ValueAnimator> animTop2 = new ArrayList<ValueAnimator>();
ArrayList<ValueAnimator> animRight2 = new ArrayList<ValueAnimator>();
ArrayList<ValueAnimator> animBottom2 = new ArrayList<ValueAnimator>();
ArrayList<AnimatorSet> animatorSet2 = new ArrayList<AnimatorSet>();
ArrayList<ValueAnimator> animLeft3 = new ArrayList<ValueAnimator>();
ArrayList<ValueAnimator> animTop3 = new ArrayList<ValueAnimator>();
ArrayList<ValueAnimator> animRight3 = new ArrayList<ValueAnimator>();
ArrayList<ValueAnimator> animBottom3 = new ArrayList<ValueAnimator>();
ArrayList<AnimatorSet> animatorSet3 = new ArrayList<AnimatorSet>();
public MyView(Context context) {
super(context);
}
@Override
public void onAnimationUpdate(ValueAnimator anim) {
invalidate();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() != MotionEvent.ACTION_DOWN
&& event.getAction() != MotionEvent.ACTION_MOVE) {
return false;
}
float h = (float) getHeight();
float endY = h - 50f;
float X = event.getX();
float startY = event.getY();
int duration = (int) (500 * ((h - startY) / h));
// color
rgb.add(i, Color.rgb((int) (Math.random() * 255),
(int) (Math.random() * 255), (int) (Math.random() * 255)));
// down
animLeft1.add(i, ValueAnimator.ofFloat(X - 25f, X - 25f));
animLeft1.get(i).setDuration(duration);
animRight1.add(i, ValueAnimator.ofFloat(X + 25f, X + 25f));
animRight1.get(i).setDuration(duration);
animTop1.add(i, ValueAnimator.ofFloat(startY - 25f, endY - 25f));
animTop1.get(i).setDuration(duration);
animTop1.get(i).setInterpolator(new AccelerateInterpolator());
animTop1.get(i).addUpdateListener(this);
animBottom1.add(i, ValueAnimator.ofFloat(startY + 25f, endY + 25f));
animBottom1.get(i).setDuration(duration);
animBottom1.get(i).setInterpolator(new AccelerateInterpolator());
animatorSet1.add(i, new AnimatorSet());
animatorSet1.get(i).play(animTop1.get(i)).with(animBottom1.get(i));
animatorSet1.get(i).play(animTop1.get(i)).with(animLeft1.get(i));
animatorSet1.get(i).play(animTop1.get(i)).with(animRight1.get(i));
// skew
animLeft2.add(i, ValueAnimator.ofFloat(X - 25f, X - 25f * 2f));
animLeft2.get(i).setDuration(duration / 4);
animLeft2.get(i).setInterpolator(new DecelerateInterpolator());
animLeft2.get(i).setRepeatCount(1);
animLeft2.get(i).setRepeatMode(ValueAnimator.REVERSE);
animRight2.add(i, ValueAnimator.ofFloat(X + 25f, X + 25f * 2f));
animRight2.get(i).setDuration(duration / 4);
animRight2.get(i).setInterpolator(new DecelerateInterpolator());
animRight2.get(i).setRepeatCount(1);
animRight2.get(i).setRepeatMode(ValueAnimator.REVERSE);
animTop2.add(i, ValueAnimator.ofFloat(endY - 25f, endY - 25f * 0f));
animTop2.get(i).setDuration(duration / 4);
animTop2.get(i).setInterpolator(new DecelerateInterpolator());
animTop2.get(i).setRepeatCount(1);
animTop2.get(i).setRepeatMode(ValueAnimator.REVERSE);
animTop2.get(i).addUpdateListener(this);
animBottom2.add(i, ValueAnimator.ofFloat(endY + 25f, endY + 25f));
animBottom2.get(i).setDuration(duration / 4);
animBottom2.get(i).setRepeatCount(1);
animBottom2.get(i).setRepeatMode(ValueAnimator.REVERSE);
animatorSet2.add(i, new AnimatorSet());
animatorSet2.get(i).play(animTop2.get(i)).with(animBottom2.get(i));
animatorSet2.get(i).play(animTop2.get(i)).with(animLeft2.get(i));
animatorSet2.get(i).play(animTop2.get(i)).with(animRight2.get(i));
// up
animLeft3.add(i, ValueAnimator.ofFloat(X - 25f, X - 25f));
animLeft3.get(i).setDuration(duration);
animRight3.add(i, ValueAnimator.ofFloat(X + 25f, X + 25f));
animRight3.get(i).setDuration(duration);
animTop3.add(i, ValueAnimator.ofFloat(endY - 25f, startY - 25f));
animTop3.get(i).setDuration(duration);
animTop3.get(i).setInterpolator(new DecelerateInterpolator());
animTop3.get(i).addUpdateListener(this);
animBottom3.add(i, ValueAnimator.ofFloat(endY + 25f, startY + 25f));
animBottom3.get(i).setDuration(duration);
animBottom3.get(i).setInterpolator(new DecelerateInterpolator());
animatorSet3.add(i, new AnimatorSet());
animatorSet3.get(i).play(animTop3.get(i)).with(animBottom3.get(i));
animatorSet3.get(i).play(animTop3.get(i)).with(animLeft3.get(i));
animatorSet3.get(i).play(animTop3.get(i)).with(animRight3.get(i));
animatorSet.add(i, new AnimatorSet());
animatorSet.get(i).play(animatorSet2.get(i))
.after(animatorSet1.get(i));
animatorSet.get(i).play(animatorSet3.get(i))
.after(animatorSet2.get(i));
animatorSet.get(i).start();
i++;
return true;
}
@Override
public void onDraw(Canvas canvas) {
if (i > 0) {
for (int j = 0; j < animatorSet.size(); ++j) {
if (animatorSet1.get(j) != null
&& animatorSet1.get(j).isRunning()) {
Paint paint = new Paint();
paint.setColor(rgb.get(j));
paint.setStyle(Paint.Style.FILL);
RectF oval = new RectF((Float) animLeft1.get(j)
.getAnimatedValue(), (Float) animTop1.get(j)
.getAnimatedValue(), (Float) animRight1.get(j)
.getAnimatedValue(), (Float) animBottom1.get(j)
.getAnimatedValue());
canvas.drawOval(oval, paint);
} else if (animatorSet2.get(j) != null
&& animatorSet2.get(j).isRunning()) {
Paint paint = new Paint();
paint.setColor(rgb.get(j));
paint.setStyle(Paint.Style.FILL);
RectF oval = new RectF((Float) animLeft2.get(j)
.getAnimatedValue(), (Float) animTop2.get(j)
.getAnimatedValue(), (Float) animRight2.get(j)
.getAnimatedValue(), (Float) animBottom2.get(j)
.getAnimatedValue());
canvas.drawOval(oval, paint);
} else if (animatorSet3.get(j) != null
&& animatorSet3.get(j).isRunning()) {
Paint paint = new Paint();
paint.setColor(rgb.get(j));
paint.setStyle(Paint.Style.FILL);
RectF oval = new RectF((Float) animLeft3.get(j)
.getAnimatedValue(), (Float) animTop3.get(j)
.getAnimatedValue(), (Float) animRight3.get(j)
.getAnimatedValue(), (Float) animBottom3.get(j)
.getAnimatedValue());
canvas.drawOval(oval, paint);
}
}
}
}
}
}
なお、R.layout.mainは以下のようになっている。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/container"
android:background="#ffffffff">
</LinearLayout>
android:id="@+id/container"を定義している以外は、特に何もしていない。
0 件のコメント:
コメントを投稿