4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2019-07-09

概要

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

作るもの

ボタンのタップによって画像の表示⇔非表示がトグルするやつを作ります!

作りましょう

プロジェクトを作ろう

今回はこれでいきます!
ファイル名

登場人物

プロジェクトを作ったらこの人達をいじっていきます!

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

build.gradle(app)

dataBinding{ enabled = true } をいい感じの場所に追加します!

MainViewModel.kt

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

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()でも動きます)

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>
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オブジェクトを作成して色々紐づけます。

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
    }
}

完成!

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

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?