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のアニメーションが書けるようになった!