2012年2月9日木曜日

BouncingBalls

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 件のコメント:

コメントを投稿