Android Kotlin+DataBinding+ViewModelでとりあえず動くモノを作る

# 概要
AndroidのDataBindingやViewModelの実装について手続き的な面でつまづいたことがあったので自分なりにまとめました！
「とにかく動かすための手続きが知りたい」という方に向けてサンプルコードを具体的に記述します。

## 作るもの
ボタンのタップによって画像の表示⇔非表示がトグルするやつを作ります！
<img width="300" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255096/fd79f3df-be1c-fe0f-f5be-36a6340d7fe1.png"> <img width="300" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255096/4e7a2496-b01e-4e6a-43de-0b2441f5ccee.png">


# 作りましょう
## プロジェクトを作ろう
今回はこれでいきます！
<img width="640" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255096/2c486c0a-00b4-319a-0b9c-92f0f58e3923.png">

## 登場人物
プロジェクトを作ったらこの人達をいじっていきます！

- build.gradle(app)
- MainViewModel.kt
- MainActivity.kt
- layout/activity_main.xml

### build.gradle(app)
` dataBinding{ enabled = true }` をいい感じの場所に追加します！
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255096/2c0d9f41-b3f1-e295-3ca3-27b4f293e4b8.png"/>

### MainViewModel.kt
android.arch.lifecycle.ViewModelを継承したMainViewModelを新規作成します！
こいつにデータ（今回だとフラグ）を保持させます。
`toggle()`が呼び出される度に`_flag.value`がtrue⇔falseと切り替わるイメージです。

```kotlin:MainViewModel.kt
class MainViewModel : ViewModel() {
    private val _flag = MutableLiveData<Boolean>().apply {
        value = false
    }

    val flag: LiveData<Boolean>
        get() = _flag

    fun toggle() {
        _flag.postValue(!(flag.value ?: false))
    }
}
```

### activity_main.xml
レイアウトファイルと、ついでにstringsファイルを弄ります！
バインディングされたオブジェクトのgetterは勝手に剥いてくれるので、三項演算子の部分は`viewModel.flag`と書いています。
（`viewModel.getFlag().getValue()`でも動きます）

```xml:activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    <data>
        <variable
                name="viewModel"
                type="com.rodentia6.sampledatabinding.MainViewModel"/>
        <import type="android.view.View"/>
    </data>

    <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".MainActivity">

        <ImageView
                android:id="@+id/image"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:visibility="@{viewModel.flag ? View.VISIBLE : View.GONE}"
                app:srcCompat="@android:drawable/star_on"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintBottom_toTopOf="@id/button"
                app:layout_constraintLeft_toLeftOf="parent"
                android:contentDescription="@null"/>

        <Button
                android:id="@+id/button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginBottom="80dp"
                android:text="@{viewModel.flag ? @string/kesu : @string/tukeru}"
                android:onClick="@{(v) -> viewModel.toggle()}"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent" />

    </android.support.constraint.ConstraintLayout>
</layout>
```
```xml:values/strings.xml
<resources>
    <string name="app_name">SampleDataBinding</string>
    <string name="tukeru">つける</string>
    <string name="kesu">けす</string>
</resources>
```

### 一旦リビルドをかける
DataBindingのクラスを自動生成してもらうために一旦リビルトします！(上メニューから Build > Rebuild Project)
何かが間違っていた場合はこの時点でエラーが発生します。

### MainActivity.kt
Activityのクラスを編集します！
ViewModelオブジェクトとDataBindingオブジェクトを作成して色々紐づけます。

```kotlin:MainActivity.kt
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // ViewModelオブジェクトを生成する
        val viewModelFactory: ViewModelProvider.Factory = ViewModelProvider.NewInstanceFactory()
        val viewModelProvider = ViewModelProvider(this, viewModelFactory)
        val viewModel: MainViewModel = viewModelProvider.get(MainViewModel::class.java)
        // 上記3行のコードは、build.gradle(app)にimplementation 'android.arch.lifecycle:extensions:1.1.1'を追加すると下記で代替できるようになる
        // val viewModel: MainViewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)

        // Bindingオブジェクトを生成する
        val binding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        // 色々紐付ける
        binding.viewModel = viewModel
        binding.lifecycleOwner = this
    }
}
```

### 完成！
おめでとうございます、完成です！起動して触ってみましょう！
画面を回転してもフラグの状態が維持されていることがわかりますね。