Lottieのダークモード対応

## はじめに

私はダークモード機能が出る前からアニメーション部分は掲題の[Lottie](https://lottiefiles.com/jp/)を使っていました。
プロダクト開発でダークモード対応するにあたり対応時調べたことを整理します

## Lottie導入手順(without compose)

前準備としてBuild.gradle(app)に以下を追加
```gradle
dependencies {
  implementation 'com.airbnb.android:lottie:$lottieVersion'
}
```
### Before(ダークモード対応:ひと手間必要)
1. アニメーションするJson(ここではlike_animation.json, like_animation_dark.jsonを使うとします)をassetsディレクトリに階層を掘って置く(app/src/main/assets/lottie)

2-1. アニメーションさせたい箇所にXMLで埋め込む

```xml
<com.airbnb.lottie.LottieAnimationView
    android:id="@+id/likeView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:lottie_fileName=“lottie/like_anumation.json"
    app:lottie_loop="true"
    app:lottie_autoPlay="true" />
```
上記は見て分かる通りダークモード用とライトモード用のJsonを分けて保存できないため、MVVMでViewModelでダークモードか判定して、渡すJsonを切り替えるかViewを2つ用意してVisibilityでライトかダークかで切り替える等の対応になるかと思います
※MVVMでやるなら以下のようになる(ViewModelでダークモード判定用メソッドがある前提)

 ```xml
 <com.airbnb.lottie.LottieAnimationView
    android:id="@+id/likeView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:lottie_fileName=“@{viewModel.isDarkMode ? lottie/like_anumation_dark.json : lottie/like_anumation.json}"
    app:lottie_loop="true"
    app:lottie_autoPlay="true" />
 ```

2-2. 動的に表示させたい場合は以下な感じです

```kotlin
assets.open(“lottie/like_anumation.json”).use { inputStream ->
    val lottieResult: LottieResult<LottieComposition> =
        LottieCompositionFactory.fromJsonInputStreamSync(
            inputStream,
            "like_anumation.json"
        )
LottieDrawable().apply {
    composition = lottieResult.value
    repeatCount = LottieDrawable.INFINITE
    addAnimatorListener(object : AnimatorListenerAdapter() {
        override fun onAnimationEnd(animation: Animator) {
            super.onAnimationEnd(animation)
            binding.likeView = ResourcesCompat.getDrawable(
                resources,
                R.drawable.like_normal,
                null
            )
        }
    })
}.playAnimation()
```
上記動的対応版も同様に、ネイティブコード側でダークモードかどうかの判定を入れる必要があります


### After(ダークモード対応:楽)
1. アニメーションするJson(ここではlike_animation.jsonを使うとします)をrawディレクトリ、raw-nightディレクトリに置く(app/src/main/res/raw and app/src/main/res/raw-night)
※公式ドキュメントには特にダークモード対応として記載がないですが[ソース](https://github.com/airbnb/lottie-android/pull/1352/files)に実装がありました

2-1. アニメーションさせたい箇所にXMLで埋め込む

```xml
<com.airbnb.lottie.LottieAnimationView
    android:id="@+id/likeView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:lottie_rawRes=“like_anumation.json"
    app:lottie_loop="true"
    app:lottie_autoPlay="true" />
```

2-2. 動的に表示させたい場合は以下な感じです

```kotlin
val lottieResult: LottieResult<LottieComposition> =
    LottieCompositionFactory.fromRawResSync(
        this@MainActivity,
        R.raw.like_animation
    )

LottieDrawable().apply {
    composition = lottieResult.value
    repeatCount = LottieDrawable.INFINITE
    addAnimatorListener(object : AnimatorListenerAdapter() {
        override fun onAnimationEnd(animation: Animator) {
            super.onAnimationEnd(animation)
            binding.likeView = ResourcesCompat.getDrawable(
                resources,
                R.drawable.like_normal,
                null
            )
        }
    })
}.playAnimation()
```
colorのダークモード対応等と同様にnight用のディレクトリに同名Jsonを置くだけでXMLでも動的対応版でもよしなにやってくれました

## まとめ
あまり意識せず[公式の手順](https://github.com/airbnb/lottie/blob/master/android.md)通り `app:lottie_rawRes`を使っていればはまらなかった問題でした
もしもLottieを使っていて、同じような問題に当たってしまった方の参考になったら幸いです