Lottie-androidを使用してFavoriteStarを実装する方法

# はじめに
dex.fmというAndroidのテック系Podcastのep20で、Airbnbの`Epoxy`と`Lottie`という2つのOSSライブラリを紹介していました。
このうち、`Lottie`はアニメーションを簡単に実現できるライブラリで、`Android`の他にも`iOS`や`React Native`に対応した`Lottie`ライブラリが提供されているようです。
詳細は以下を参照ください。
https://medium.com/airbnb-engineering/introducing-lottie-4ff4a0afac0e#.dmmsfvxy5

`Epoxy`と`Lottie`はどちらも面白そうだったのですが、趣味で作成しているアプリが丁度「お気に入りボタン」の実装で悩み中だったため`Lottie`を使ってみようと調査をはじめました。
日本語の情報が少なくてうーむと思ったのですが、GithubのREADME.mdがかなり丁寧だったので結構簡単に導入できました。そのため、あまり需要はないかもしれませんがせっかくなのでメモを残すことにしました。

# 書くこと
`lottie-android`のサンプルにあるFavorite Starを使用し、タップしたらアニメーションとともにスターが色塗りされ、再びタップしたら白に戻る、というサンプルを作りました。
その要点部分を書きます。作ったサンプルはこんな感じです。小さいですが・・・

![サンプル](https://qiita-image-store.s3.amazonaws.com/0/38780/df3a1b2e-bc40-8f15-28d5-e7c527535b5c.gif)

ここではプロジェクト作成などの細かい手順は記載しません。サンプルコードはGithubに上げておきますのでそちらをご参照ください。
https://github.com/hotdrop/favostar-sample-android
（Android studioでサンプルプロジェクトを作成し、テンプレートはEmpty Activityにして最低限のコードだけ書いています。）

また、本記事で紹介する内容は`Lottie`ができることのほんのごく一部です。
GithubのREADME.mdでも色々なgifが貼られているようにかなり多種多様なアニメーションが実現できそうです。

# 使用条件
どうせAPIレベル23とかなんだろ、と思ったらREADME.mdに以下のように書かれていました。

> Lottie supports ICS (API 14) and above.

なお、今回私が検証した環境はkitkat(API 19)です。

# 1.build.gradleの編集
`Lottie`を使用するためbuild.gradleに以下を追加してください。

```build.gradle
compile 'com.airbnb.android:lottie:1.5.3'
```

# 2.アニメーションのjsonファイルを用意
`Lottie`ではアニメーションを`json`形式で表現しています。`Lottie`プロジェクトの[サンプル](https://github.com/airbnb/lottie-android/tree/master/LottieSample/src/main/assets)を参照ください。
今回はここから **lottiefiles.com - Favorite Star.json** を使用させていただくことにします。
自身のプロジェクトの`Assets`ディレクトリに`json`ファイルを置いてください。
なお、`lottiefiles.com - Favorite Star.json`というファイル名は長いので自プロジェクトに持ってきたとき`FavoriteStar.json`にリネームしました。

# 3.layoutへAnimationViewを追加
アニメーションのViewは全てこの`LottieAnimationView`で定義します。
`lottie_fileName`で指定している`json`ファイルは`Assets`ディレクトリ直下に置いています。
`json`ファイルは`xml`ではなくコード中で指定することも可能です。
詳細は`Lottie`のREADME.md(Using Lottieの章)を参照してみてください。

```xml:layout
<com.airbnb.lottie.LottieAnimationView
    android:id="@+id/animation_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:lottie_fileName="FavoriteStar.json"
    app:lottie_loop="false"
    app:lottie_autoPlay="false" />
```

# 4.アニメーションの実装
javaコードは以下の通りです。

```java:実装部分

// AnimationViewのクリック状態を保持するためのフィールドです。
private boolean clickedFav = false;

/* この間は省略 */

final LottieAnimationView animationView = (LottieAnimationView) findViewById(R.id.animation_view);
animationView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if(clickedFav) {
            // setProgress(0f)でアニメーション開始前状態にします。
            animationView.setProgress(0f);
            clickedFav = false;
        } else {
            animationView.playAnimation();
            clickedFav = true;
        }
    }
});
```

私はあまりアニメーションに慣れていないため「あれ？どうやってスターのON/OFFを表すんだ？」というのが一瞬分かりませんでした。
アニメーションなので「スターが付いていない/スターが付いている」という２つの状態ではなく、アニメーションとして連続した状態になるのですね。
スターが付いていない状態は`setProgress(0f)`で表せます。これはアニメーションのタイムバー的なものを0秒地点に設定するイメージです。
`setProgress(1f)`とすると、アニメーションが完了した状態になります。最初からスターが付いた状態にしたい場合はこれにします。
`setProgress(0.5f)`とするとスターのアニメーションが途中で止まった状態になります。
これはLottieのサンプルアプリを動かしたらすぐ分かりました。
今回は「クリックしてない/クリックした」という２つの状態だけ欲しかったので`boolean(clickedFav)`で表現しました。

# まとめ
今回は簡単にFavoriteStarのみ紹介しましたが、他のアイコンっぽいアニメーションも同じ理屈で扱えるはずです。サンプルでは面倒だったのでActivity上に配置しましたが例えばリストの`CardView`に`LottieAnimationView`を追加すればアイテム毎のお気に入りボタンが簡単に実装できます。

また、冒頭でも書きましたがこの記事は`Lottie`のほんの触りで、結構凝ったアニメーションも色々と実現できるようです。
Githubの`Lottie`リポジトリにはLottieSampleというサンプルアプリも一緒にあって、色々なアニメーションを触ることができます。
また、これとほとんど同じものだと思いますがGooglePlayストアでもサンプルアプリが提供されています。
サンプルの割になんか色々と凝っていて凄い出来が良いので、興味を持った方は触ってみると良いかもしれません。