LoginSignup
32
18

More than 3 years have passed since last update.

[Android] もっと!Lottie

Last updated at Posted at 2019-04-05

【移行のお知らせ】プライバシー上の懸念により、Qiitaアカウントの削除を検討しています。
各投稿は個人blog( https://gateau.hatenablog.com/archive/category/Qiita )に移行しました。
今後も参照される方は、ブックマークなど移行をお願い致します。


Lottie( http://airbnb.io/lottie/ )はAirbnb社が開発・公開しているアニメーションライブラリです。
アニメーションのjsonさえあれば、ImageViewと似た指定で簡単に扱えます。サンプルアプリ を入れてみると挙動がわかりやすいです。
jsonの作り方は他のドキュメントに任せて、Androidの実装側で色々やってみた例を紹介します。

きほん

アプリ内のassetsなどに置いたjsonを読み込む

 <com.airbnb.lottie.LottieAnimationView
         android:id="@+id/lottie_view"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         app:lottie_fileName="hello_world.json"
         app:lottie_loop="true"
         app:lottie_autoPlay="true" />

アプリ内に置かず、URLで指定する

 <com.airbnb.lottie.LottieAnimationView
         android:id="@+id/lottie_view"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         app:lottie_url="https://xxxxx/hello_world.json" />

もっと!

可変なURLを指定する

サーバからjsonのURLを取得して、その内容を表示させたいとき。これはxmlだけでは出来なくて、コードを書くことになります。

lottieView.setAnimationFromUrl(url)

この指定で表示はされます。しかし、URLが存在しなかったりロード出来なかったときに IllegalStateException が投げられてしまいます。
たぶんこの部分 https://github.com/airbnb/lottie-android/blob/master/lottie/src/main/java/com/airbnb/lottie/LottieAnimationView.java#L66

private final LottieListener<Throwable> failureListener = new LottieListener<Throwable>() {
    @Override public void onResult(Throwable throwable) {
        throw new IllegalStateException("Unable to parse composition", throwable);
    }
};

落ちないように次のようにしました。

LottieCompositionFactory.fromUrl(this, url)
        .addFailureListener {
            // 読み込み失敗時の処理
        }
        .addListener {
            lottieView.setComposition(it)
        }

コードで動的に指定するときは lottieView.playAnimation() を忘れるとアニメーションが開始しないので注意です。

アニメーションが終わったら消す

AnimatorListenerかAnimatorListenerAdapterのListenerをセットし、アニメーションの開始や終了時の処理を記述できます。

lottieView.addAnimatorListener(object : AnimatorListenerAdapter() {
    override fun onAnimationEnd(animation: Animator?) {
        lottieView.visibility = View.GONE
    }
})

複数のアニメーションを連続して表示する

サーバから1つずつ表示したいアニメーションのURLを取得し、それをQueueに詰めてみることにしました。

private val lottieQueue: LinkedList<String> = LinkedList()
private val animationListener = object : AnimatorListenerAdapter() {
    override fun onAnimationEnd(animator: Animator) {
        playNextLottie()
    }
}
// 〜〜〜
{ // どこかでサーバから1つずつ取得する
    lottieQueue.add(enqueueURL) // 複数詰める
    playNextLottie()
}
// 〜〜〜
private fun playNextLottie() {
    val lottieUrl = lottieQueue.pollFirst()
    if (lottieUrl.isNullOrEmpty()) { // Queueから全てなくなったら終了
        disableLottieView() // listener解除など終了処理
        return
    }
    buildAndPlayLottieView(lottieUrl)
}

private fun buildAndPlayLottieView(url: String) {
    LottieCompositionFactory.fromUrl(context, url)
             .addFailureListener {
                 playNextLottie() // リンク切れなどのときは何もせず次へ
             }
             .addListener {
                 lottieView.setComposition(it)
                 lottieView.addAnimatorListener(animationListener)
                 lottieView.playAnimation()
             }
}

その後、これらの処理はcom.airbnb.lottie.LottieAnimationView を継承したCustomViewをつくって突っ込みました。

動的に取得したLottieを画面の横幅目一杯に表示する

match_parent して伸びるのはアニメーションの背景だけだったので、scaleを設定してみました。

LottieCompositionFactory.fromUrl(this, url)
        .addListener { lotteCompotition ->
           lottieView.scale = lottieView.measuredWidth.toFloat() / lotteCompotition.bounds.width()
        }

アスペクト比が固定なのであれば、 app:layout_constraintDimensionRatio で縦横比を指定して match_constraint でもいけてました。
scaleTypeも使えますが、 centerCropcenterInside しか使えないので注意です。

こまった!

おちた!

json内でフォントの指定がされており、そのフォントが見つからなかったときに落ちました。次のエラーが出ました。

Font asset not found fonts/BlackHanSans.ttf

特に文字は使っていなかったので、フォント指定のないjsonを作り直してもらいました。

でない!

ViewよりLottieが大きいと表示されませんでした。scaleで調整したりしました。

おもい!

古い端末だともっさりすることがあります。json側の作り方の方は詳しくないので、軽く作る良い方法があったら知りたいです。

おわりに

アニメーションはうまく使うとわかりやすいし楽しいです。参考になる記事などをいくつか載せておきます。良いLottieライフを!

32
18
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
32
18