Jetpack を使って、ビューモデルに沿った Android アプリを Kotlin で作成（2時間）

## TL; DR

![Jetpack](https://qiita-image-store.s3.amazonaws.com/0/28930/979f4686-932d-8416-eb8e-c9d93b0d94ce.png)


- Jetpack はアーキテクチャやUIその他色々の面倒を見てくれるすごいやつ
  - 自動でビューモデルのアーキテクチャでスケルトンを作ってくれる
- [公式のページの導入手順](https://developer.android.com/jetpack/docs/getting-started)に沿うと、ライブラリのインポートに失敗してビルドが正常完了しない（2018/05/22現在）
- 動くサンプルはこちら 三 ( ◠‿◠ )☛ [dogwood008/calc](https://github.com/dogwood008/calc)

## Jetpack とは？

Google I/O 2018 で新たに発表された、ツールとライブラリ。以下の4つで構成される。

<figure class="figure-image figure-image-fotolife" title="Jetpackで使用できるもの">
<a href="https://developer.android.com/jetpack/" target="_blank">
<img src="https://qiita-image-store.s3.amazonaws.com/0/28930/6b088608-23d0-8cb6-e6d2-3177a5afde07.png" alt="ファウンデーション、アーキテクチャ、ビヘイビア、UI"/>
</a>
<figcaption>Jetpackで使用できるもの</figcaption>
</figure>

- ファウンデーション
  - AppCompat （後方互換性サポート）
  - Multidex （メソッド数上限開放）
  - テストフレームワーク 等
- アーキテクチャ
  - データバインディング
  - ナビゲーション
  - ビューモデル 等
- ビヘイビア
  - 通知
  - パーミッション
  - 共有 等
- UI
  - アニメーション＆トランジション
  - 絵文字
  - レイアウト

[Android Jetpack | Android Developers](https://developer.android.com/jetpack/)

## Jetpack があると何が嬉しいの？

「Androidアプリ作りたいけど、アーキテクチャがいっぱいあってよくわからん」という人におすすめ。公式から提示された Jetpack により、これに乗っかっておけばなんとかなるという道が示された。

他にも上に挙げたようなもののうち、欲しいものだけつまんで導入することもできるので、車輪の再発明やボイラープレート（テンプレ）を引っ張り出してくる手間が省ける＆（自分で書かなくてすむので）保守しやすくなるといったメリットがある。


## Jetpackの導入

まずは Android Studio 3.2 が必要。でもまだ正式版は出ていないので `Check for Update` では振ってこない。ので直接zipをDLして展開する。

[Preview release](https://developer.android.com/studio/preview/)

プロジェクトをいつも通り新規作成する。

![新規作成](https://qiita-image-store.s3.amazonaws.com/0/28930/b974c86b-f8a2-77a6-6cfd-20a7093bd662.png)


いつもの通り進めていくと、見慣れないやつ `Activity & Fragment + ViewModel` がいる。これを選択して次へ。

![Activity & Fragment + ViewModel](https://qiita-image-store.s3.amazonaws.com/0/28930/d8df6032-c1da-4e3c-c454-fce23e4dcc07.png)



そうすると、アクティビティとフラグメントの名前に加え、ビューモデルの名前を決める画面が表示される。特に指定がなければデフォルトのままで完了。

![ビューモデルの名前を決める](https://qiita-image-store.s3.amazonaws.com/0/28930/98150d19-7bd5-511d-5cc9-1efdd497eca8.png)


## Jetpack を使った実装

ビューモデルを実装していく。デフォルトのままだと、（Kotlinサポートにチェックを入れていれば）　`MainViewModel.kt` でビューモデルのクラスが定義されている。下記を入力して実装する。


```kotlin:MainViewModel.kt
import android.arch.lifecycle.LiveData
import android.arch.lifecycle.MutableLiveData
import android.arch.lifecycle.ViewModel

class MainViewModel : ViewModel() {
    private val _data = MutableLiveData<String>()
    val data: LiveData<String>
        get() = _data

    init {
        _data.value = "Hello, Jetpack!"
    }
}
```

続いて、実行に必要なライブラリをインポートする。

この手順では下記を変更せず書くことをおすすめします。<span style="color: #ff0000"><b>もし[原著](https://developer.android.com/jetpack/docs/getting-started)の手順に従うとビルドに失敗するので注意！</b></span>


```kotlin:build.gradle
// LiveData + ViewModel
def archLifecycleVersion = '1.1.1'
implementation "android.arch.lifecycle:extensions:$archLifecycleVersion"

// Navigation
def navigationVersion = '1.0.0-alpha01'
implementation "android.arch.navigation:navigation-fragment:$navigationVersion"
implementation "android.arch.navigation:navigation-ui:$navigationVersion"
```

最後に `MainFragment.kt` でビューモデルから取得した値を TextView に代入する。



```kotlin:MainFragment.kt（抜粋）
override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)
    viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
    val text = viewModel.data.value
    message.text = text
}
```

これでおしまい。あとはビルドしたら `Hello, Jetpack!` が表示される。

![Hello, Jetpack!](https://qiita-image-store.s3.amazonaws.com/0/28930/a3967b8a-5f4e-94ef-4b06-57d3aed7cbe4.png)


今回のリポジトリはここに置いておきます。

https://github.com/dogwood008/calc
（電卓を作りたかったけど、2時間で記事書きながらじゃちょっと無理だった）


## 感想

正直アーキテクチャなんて好き好みあるし、どれが自分に・チームに最適かはわかんないよな～という人向けに、 「Jetpackを使ったら自動的にビューモデルである程度用意してくれる」というのが自分は好き。 Rails と比べるとやや物足りない感もあるが、「ディレクトリに意味があって、名前を勝手に変えると破滅して、……」というよりは初めてでもとっつきやすいので、その点を加味するとこれくらいで良いのかも。

もし記事中に誤りがあれば、 [@dogwood008](https://twitter.com/dogwood008) までご連絡いただけると幸いです 🙇

## 参考

- ["Hello, Jetpack": Build your first Jetpack app](https://developer.android.com/jetpack/docs/getting-started)