t_t_nの日記

開発の備忘録など

droidkaigiいってきた

行ってきた

仕事の合間に行ったので対して聞けなかったけれども、結構勉強になりました。
英語のスピーチを試しに聞いてみたけど辛いだけだった。英語勉強しなきゃ()

今回は聞いた内の一つ、「実践アニメーション」のサンプルを読む。

xmlで複雑なアニメーションは聖域になるからやめた方が良い、ってのが一番印象に残ってる。

Androidのアニメーションの基本部分の簡単なサンプルたちはスルーして、
花火してたところを見る。

MarbleAnimationってところかなぁ多分


まずは呼び出し側
MarbleAnimationActivity.java

animatorView = (MarbleView) findViewById(R.id.animatorView);

        animatorView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                animatorView.startCustomAnimation();
            }
        });

ほんとに呼ぶだけって感じ。カスタムのView + ValueAnimator最強って言ってたから、
その通りの作りになってるんだな、って。


というわけで本体
MarbleView.java

private void initParams() {
        maxDistance = getContext().getResources().getDimensionPixelSize(R.dimen.marble_max_distance);
        circleRadius = getContext().getResources().getDimensionPixelSize(R.dimen.marble_max_circle_radius);
    }

Viewの拡張クラスの中でgetContextって出来るんだ・・!(無知)
コンストラクタで必ず渡してるんだから当たり前かぁ

上記の個所は初期値を定義している部分で、すべてのコンストラクタで呼び出していた。
外から渡したりはしないんすねーってちょっと思ったけど、設定値を書き換えろやって話か

// 外の公開しているのはこのメソッドだけみたい
 public void startCustomAnimation() {
        if (isRunning) return;

        isRunning = true; // このフラグを折ってるところが見当たらない
        for (int i = 0; i < animators.length; i++) { // animatorsはValueAnimatorの配列で20個
            createAndStart(i);
        }
    }


20個のValueAnimatorを作成してるみたい。
花火の各点になるのかな?なるんじゃないかな?

private ValueAnimator createAnimator() {
        Random random = new Random();
        ValueAnimator animator = ValueAnimator.ofPropertyValuesHolder(
                PropertyValuesHolder.ofFloat(VELOCITY_X, (random.nextFloat() - 0.5f) * 2),
                PropertyValuesHolder.ofFloat(VELOCITY_Y, (random.nextFloat() - 0.5f) * 2),
                PropertyValuesHolder.ofFloat(PROGRESS, 1.0f));
        animator.setDuration(random.nextInt(MAX_DURATION / 2) + MAX_DURATION / 2);
        animator.setInterpolator(new DecelerateInterpolator()); // 最初速くて減速する。花火だ。
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                invalidate(); // これを使ってonDrawを呼び出している様子
            }
        });
        return animator;
    }

一番知りたかった部分・・・かな?
valueAnimatorで値が変化するとonAnimationUpdateが呼ばれるみたい。
そこでinvalidateすることでonDrawを呼んでいる。

setInterpolatorって何だろうと思って調べたけど、スライドにちゃんと書いてた。

private void drawPhotons(Canvas canvas) {
        for (int i = 0; i < animators.length; i++) {
            float velocityX = (float) animators[i].getAnimatedValue(VELOCITY_X);
            float velocityY = (float) animators[i].getAnimatedValue(VELOCITY_Y);
            float progress = (float) animators[i].getAnimatedValue(PROGRESS);
            paints[i].setAlpha(255 - (int) (255 * progress));
            canvas.drawCircle(maxDistance * velocityX + centerOfX(),
                    maxDistance * velocityY + centerOfY(),
                    circleRadius * progress,
                    paints[i]);
        }
    }


最後、onDraw内で呼んでいるメソッド。
ValueAnimatorで動きを定義して、ここで実際の描画を行っているっぽい。
色はcreatePaintメソッドの方でランダムで定義してた。

drawCircleで行っている計算は速度をうまく使ってやってるみたい。
つまり、ランダムで発生した速度を点のサイズに反映することで、速い点はでっかく、
小さい点はちっこくなる・・んじゃないかなぁ。

progressって何だろう・・・

xmlで書くよりは確かに読みやすそう。でも描画を行っている部分が多少複雑になりそう。

これでAndroidのアニメーションが書けるようになった!