Kotlinで基本的なData Bindingを行うための手順です。
Kotlinファイルがビルドできるようになっているのが前提です。
Android Studio 2.1における記述です。
全体の流れ
- build.gradleにData Bindingを使うように設定する
- バインドするモデルクラスを作成する
- Layoutファイルを編集する
3. XMLで開き、layout
タグを全体の親要素とするよう追加する
4.layout
タグの子要素にdata
タグを追加する
5. これはバインドされるモデルと対応する
6. バインドしたい属性に@{モデルの名前.プロパティ}
と書く - ビルドし、Bindingクラスを自動生成する
- アクティビティ内でBindingクラスを使いバインドするモデルクラスのインスタンスを指定する
GradleでData Bindingを有効にする設定を行う
Moduleのbuild.gradle に下記を設定
Data Bindingを有効にするための設定
android {
....
dataBinding {
enabled = true
}
}
Kotlin上でもBindingクラスを自動生成できるようにするための設定
dependencies {
...
kapt 'com.android.databinding:compiler:1.0-rc5'
}
kapt {
generateStubs = true
}
バインドするモデルを作成する
Kotlinっぽくdata classを使ってみます。
基本編として動作を確認するため、このデータクラスを直接バインドする予定です。
Book.kt
data class Book(val title: String, val price: Int, val authors: List<Author>)
Author.kt
data class Author (val name: String)
レイアウトを作成する
全体を<layout>
タグで括る
- レイアウトファイルをText形式で開き、
<layout>
タグで全体を括る
2. 下記属性が重複するとビルドエラーになるので、<layout>
タグの属性のみに存在するようにするため、他は削除する
*xmlns:android="http://schemas.android.com/apk/res/android"
- バインドするモデルを
<data>
タグ内で定義する
このようになる。
MainActivity.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- 全体を layout で括る -->
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<!-- layout の子要素に data タグを追加-->
<!-- name が layoutの中で参照するときの名前に対応
type は バインドするモデルクラスのFQNとする -->
<data>
<variable
name="book"
type="com.example.kotlinsample.model.Book" />
</data>
<RelativeLayout
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.example.kotlinsample.MainActivity">
...省略...
</RelativeLayout>
</layout>
バインドするWidgetを配置し、どこに何をバインドするかを定義する
- 適当にバインドするWidgetを配置(今回はTextViewを2つ配置)
MainActivity.xml
<TextView
...
android:text="@{book.title}"
android:id="@+id/bookName"
....
/>
<TextView
....
android:text="@{book.authors.size() + "人"}"
android:id="@+id/authorsCount"
....
/>
-
@{ }
の中にバインドしたい要素を書く - dataタグのname属性で定義した名前でバインドするオブジェクトにアクセスができる
- ある程度はxml上で表現できる
リビルドして、Bindingクラスを自動生成させる
- リビルドを実行すると、ここまでの手順を踏んでいれば作成される
Activity内でバインドを指示する
MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// バインドするデータを作成。今回は手で作成
val author1 = Author(name = "一郎")
val author2 = Author(name = "次郎")
val book = Book(title = "とても良い本", price = 1000, authors = arrayListOf(author1, author2).toList())
val mainActivityBinding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
mainActivityBinding.book = book
}
最後の行で book に波線が出てエラーメッセージがでるが動作は問題ない。
エラーメッセージは Cannot access class '....' Check your module classpath ...
これについては、 バグ報告されている。
確認
- 実行するとバインドされていることが確認できます