LoginSignup
47
37

More than 5 years have passed since last update.

変なInterpolatorの使い方

Last updated at Posted at 2015-12-17

どうも、@amyu_sanです。

本稿はDroidKaigi2016にCFPで出した内容の一部書き出しとなります。

お断り

Interpolatorの解説は一切しないため、Interpolatorは何かを知りたい場合には全く役に立ちません。
Interpolatorを知りたい場合はググっていただくか、

などなどをぜひご参考ください。

また、本稿の最後に今回作ったViewのサンプルコードを公開したGithubへのリンクを貼っておきます。
そのため、コードを一部抜粋して解説します。

今回作るもの


recruit-lifestyle/WaveSwipeRefreshLayoutの円が落ちた時にバウンドするAnimationです。

もっと近寄ってみると、このようなアニメーションになっています。
ezgif.com-crop (11).gif

様々な実装方法があるとは思いますが、実際に実装したInterpolatorの使い方をご紹介します。

Interpolatorの用意


public class DropBounceInterpolator implements Interpolator {

    public DropBounceInterpolator() {
    }

    @SuppressWarnings({"UnusedDeclaration"})
    public DropBounceInterpolator(Context context, AttributeSet attrs) {
    }

    @Override
    public float getInterpolation(float v) {
        //y = -19 * (x - 0.125)^2 + 1.3     (0 <= x < 0.25)
        //y = -6.5 * (x - 0.625)^2 + 1.1    (0.5 <= x < 0.75)
        //y = 0                             (0.25 <= x < 0.5 && 0.75 <= x <=1)

        if (v < 0.25f) {
            return -38.4f * (float) Math.pow(v - 0.125, 2) + 0.6f;
        } else if (v >= 0.5 && v < 0.75) {
            return -19.2f * (float) Math.pow(v - 0.625, 2) + 0.3f;
        } else {
            return 0;
        }
    }
}

コードだけではわかりにくいので、実際どういうグラフになっているのか解説します。
252b1203d113c386c1dd9532d5d7c1a2.png

各グラフのx軸との接点どうしが、0.25ずつ、グラフ間を0.25とった数式になっています。
勘の良い方はこのグラフと上記のGifで実装方法が考えつくかと思います。

Viewの実装と解説


//横方向への伸びのAnimator
mDropBounceVerticalAnimator = ValueAnimator.ofFloat(0.f, 1.f);
mDropBounceVerticalAnimator.setDuration(DROP_BOUNCE_ANIMATOR_DURATION);
mDropBounceVerticalAnimator.addUpdateListener(mAnimatorUpdateListener);
//Interpolatorのセット
mDropBounceVerticalAnimator.setInterpolator(new DropBounceInterpolator());
mDropBounceVerticalAnimator.start();

mDropBounceHorizontalAnimator = ValueAnimator.ofFloat(0.f, 1.f);
mDropBounceHorizontalAnimator.setDuration(DROP_BOUNCE_ANIMATOR_DURATION);
mDropBounceHorizontalAnimator.addUpdateListener(mAnimatorUpdateListener);
mDropBounceHorizontalAnimator.setInterpolator(new DropBounceInterpolator());
mDropBounceHorizontalAnimator.setStartDelay((long) (DROP_BOUNCE_ANIMATOR_DURATION * 0.25));
mDropBounceHorizontalAnimator.start();

本稿のキモとなってくる部分が


mDropBounceHorizontalAnimator.setStartDelay((long) (DROP_BOUNCE_ANIMATOR_DURATION * 0.25));

この縦伸びのAnimatorにDelayを設定する部分になっています。
グラフで見て分かる通り0.25ずつずらしていたため、Delayを0.25*mDropBounceVerticalAnimator#Durationにしています。

すると、時間 0~1の間に以下のようになります。

赤色のグラフが横方向、青色のグラフが縦方向になっています。
横の伸びが終わった瞬間に縦がうまく始まるアニメーションを実装できているのが分かります。

うまくValueAnimatorを設定できたら、サクッとonDrawの中身を書けば完成です。

まとめ

An interpolator defines the rate of change of an animation. This allows the basic animation effects (alpha, scale, translate, rotate) to be accelerated, decelerated, repeated, etc.

と、Interpolatorの説明でありますが、使い方を工夫するだけで、様々なことが出来ます。
今回のように

  • 2段階で大きさを変えたい
  • 2段階で大きさを変えたい * 2 (縦横)

のような場合普通に脳筋で実装するとものすごいことになります。
ただ、Interpolatorを従来の使い方以外でうまく使うことによって、実装時間やコードの綺麗さも大きくかわると考えています。
Viewをゴリゴリ書くには必須のアイテムといえますね!

と言った感じで締めくくらせていただきます。

サンプル

InterpolatorSampleView

47
37
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
47
37