- 投稿日:2019-04-05T16:26:11+09:00
[Android] もっと!Lottie
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#L66private 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も使えますが、centerCrop
とcenterInside
しか使えないので注意です。こまった!
おちた!
json内でフォントの指定がされており、そのフォントが見つからなかったときに落ちました。次のエラーが出ました。
Font asset not found fonts/BlackHanSans.ttf特に文字は使っていなかったので、フォント指定のないjsonを作り直してもらいました。
でない!
ViewよりLottieが大きいと表示されませんでした。scaleで調整したりしました。
おもい!
古い端末だともっさりすることがあります。json側の作り方の方は詳しくないので、軽く作る良い方法があったら知りたいです。
おわりに
アニメーションはうまく使うとわかりやすいし楽しいです。参考になる記事などをいくつか載せておきます。良いLottieライフを!
サクッとLottieの概要がわかる記事
- lottieが大変よろしいものだった - アナログ金木犀 https://motida-japan.hatenablog.com/entry/2017/02/19/145537
jsonの作り方の話
- デザイナーとエンジニアの距離をより近づける Lottie 利用術 - DroidKaigi 2019 https://droidkaigi.jp/2019/timetable/70876
導入事例などの話
- 実践 Lottie - DroidKaigi 2019 https://droidkaigi.jp/2019/timetable/69036
- 投稿日:2019-04-05T07:59:51+09:00
PagerViewで左右どちらにフリックしたか判定する方法
/** Touch前の座標*/ private boolean mIsPagerViewTouchDown = false; pager.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { float touchX = event.getX(); switch(event.getAction()) { case MotionEvent.ACTION_DOWN: mPreviousTouchPointX = touchX; break; case MotionEvent.ACTION_UP: float dx = touchX - mPreviousTouchPointX; // TouchDown時のタッチ座標とTouchUp時の座標を比較しどちらにフリックしたか判定 if ((Math.abs(dx) > 1)) { if (dx > 0) { Log.d(MainActivity.class.getSimpleName(), "右へフリック"+dx); } else { Log.d(MainActivity.class.getSimpleName(), "左へフリック"+dx); } } break; default: break; } mPreviousTouchPointX = touchX; return false; } });
- 投稿日:2019-04-05T00:42:14+09:00
Androidのライブラリプロジェクト内のKotlinクラスを参照するとUnresolved referenceが出る問題対処
Androidプロジェクトから別のAndoridライブラリプロジェクト内のKotlinクラスを参照した時に、Unresolved referenceとなりビルドエラー発生。1hくらいはまったのでメモを残す。
原因
ライブラリプロジェクトのbuild.gradleにKotlin用の記述が漏れているため。
(Androidライブラリプロジェクト作成時、Kotolin用の記述は自動生成されない)解決方法
ライブラリプロジェクトを開いて、以下を実施。
Tools -> Kotlin -> 'Configure Kotlin in projects'
(All modules with Kotlin files are configured'を選択してOK。参考