33
25

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

Last updated at Posted at 2018-05-10

この前、Kotlin Android Extensionsを使って感動してたら、友達から、DataBinding使うのが昨今のAndroidプロジェクトでは一般的と教わったので、使ってみます。

環境

Android Studio 3.1.2

DataBindingとは

ViewModelを作っておいて、そこの値を変えれば、xml上のプロパティに自動でアクセスしてくれるものらしい。Activityに、Viewへのアクセスをごちゃごちゃ書かなくてスッキリ管理しやすくなる模様。逆にプロパティが変わったらViewModelの値を変えるということもできるらしい。

簡単なサンプルを作ってみる

今回は、ViewであるTextViewtextと、ViewModelnameを紐付けしてみたいと思います。

MyAppAという名前でプロジェクトを作ったら、build.gradleに2箇所追加します。

app/build.gradle
apply plugin: 'kotlin-kapt' // ここを追記

android {
    ...
    // ここを追記
    dataBinding {
        enabled = true
    }
}

続いて、viewmodelフォルダを作成し、その中に MainViewModel クラスを作成。

MainViewModel.kt
package com.funeasysoft.myappa.viewmodel

class MainViewModel {
    var name = "funeasy"
}

紐づける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">

    <data>

        <variable
            name="viewModel"
            type="com.funeasysoft.myappa.viewmodel.MainViewModel" />
    </data>

    <android.support.constraint.ConstraintLayout xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{viewModel.name}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </android.support.constraint.ConstraintLayout>
</layout>

元々のLayoutを、<Layout> で囲み、<data>を追加し、ViewModelクラスを指定している。また、今回はTextViewtextとdataBindingするために、android:text="@{viewModel.name}"とします。

ここで注意が必要で、元々ConstraintLayoutに付いている
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
は、消しておかないといけない。
消さないと以下のようなエラーになってしまう。

error: duplicate attribute.
Message{kind=ERROR, text=error: duplicate attribute., sources=[/Users/masa/DevAndroid/MyAppA/app/src/main/res/layout/activity_main.xml:13], original message=, tool name=Optional.of(AAPT)}

最後にActivityへ、関連付けします。

MainActivity.kt
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // setContentView(R.layout.activity_main) // コメントアウト

        val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
        binding.viewModel = MainViewModel()
    }

実行すると、画面に、 MainViewModel クラスの name に入れた funeasy が表示されました。

image.png

ボタンをクリック -> TextViewを変える

buttonClicked()を追加します。また、viewModel.name が変更されたら、表示もかわるように、ObservableField("[初期値]")に変更します。

MainViewModel.kt
package com.funeasysoft.myappa.viewmodel

import android.databinding.ObservableField

class MainViewModel {
    var name = ObservableField("funeasy")

    fun buttonClicked() {
        name.set("Button clicked!")
    }
}

Buttonを追加、android:onClick="@{() -> viewModel.buttonClicked()}"を設定しておく。

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <variable
            name="viewModel"
            type="com.funeasysoft.myappa.viewmodel.MainViewModel" />
    </data>

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

        <TextView
            android:id="@+id/textView"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="@{viewModel.name}"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <Button
            android:id="@+id/button"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:text="Button"
            android:onClick="@{() -> viewModel.buttonClicked()}"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/textView" />

    </android.support.constraint.ConstraintLayout>
</layout>

ボタンをタップすると、確かにテキストが変更されました!

image.png

今後色々とMainViewModelをカスタムして、どれだけ楽になるのかみていこうと思います。

33
25
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
33
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?