Android Kotlin基礎講座 02.4: データバインディングの基礎
目次
タスク:データバインディングを使ってデータを表示する
データバインディングの利点を使ってdataクラスを直接ビューから利用できるようにすることができます。このテクニックによってコードはさらに簡潔なものになり、さらに複雑なケースを扱う際に真価を発揮します。
今回の例では、stringリソースを使って名前とニックネームを設定する代わりに、名前とニックネーム用のdataクラスを作成します。データバインディングを使って、そのデータクラスをビューから利用できるようにします。
ステップ1:MyName dataクラスを作成する
- Android Studioのjavaディレクトリの中のMyName.ktファイルを開いてください。ファイルがない場合はMyName.ktという名前のファイルを作成してください。(MainActivity.ktファイルと同じ場所に作成してください)
- 名前とニックネーム用のdataクラスを定義します。空のstringをデフォルトの値に使用してください。
data class MyName(var name: String = "", var nickname: String = "")
ステップ2:レイアウトにデータを追加する
activity_main.xmlファイルの中で、名前は現在TextViewにセットされており、それはstringリソースを利用しています。この名前への参照をdataクラスのデータで置き換える必要があります。
- activity_main.xmlを開き、Textタブで表示してください。
- 一番上、<layout>と<LinearLayout>タグの間に<data></data>タグを挿入してください。この中でビューとデータを接続します。
<data>
</data>
dataタグの中でクラスへの参照をもつ変数を宣言することができます。
- <data>タグの中に<variable>タグを追加してください。
- “myName”という名前を変数に与えるために、nameパラメーターを追加してください。
typeパラメーターを追加して、MyName dataクラスの完全修飾名(package名+変数名)を設定してください。
<variable
name="myName"
type="com.example.android.aboutme.MyName" />
これで名前にstringリソースを使う代わりにmyName変数の参照を利用できます。
- android:text=”@string/name”を下記のコードに置き換えてください。
@={}は中括弧の中に記されたデータを取得するための命令です。
myNameは先ほど定義したmyName変数について言及しており、myName変数はmyName dataクラスを指示しています。そしてmyName dataクラスからnameプロパティを読みこんでいます。
android:text="@={myName.name}"
ステップ3:データを作成する
ここまででレイアウトファイル中でデータへの参照を作成しました。次は実際のデータを作成していきます。
- MainActivity.ktファイルを開いてください。
- onCreate()の上で、myprivateな変数を作成してください。慣例でこれもまたmyNameという名前に統一します。変数にMyNameデータクラスのインスタンスを代入します。インスタンスを作る際に引数に名前を渡しています。
private val myName: MyName = MyName("Aleks Haecky")
- onCreate()の中で、レイアウトファイルのmyName変数の値にたった今宣言したmyNameの値をセットします。XML内の変数に直接アクセスすることはできません。バインディングオブジェクトを介す必要があります。
binding.myName = myName
- 変更を行った後にはバインディングオブジェクトをリフレッシュする必要があるので、エラーが発生するかもしれません。その場合は一度アプリをビルドするとエラーが消えます。
ステップ4:TextViewのニックネーム用にdataクラスを使う
最後のステップはdataクラスを使ってTextViewのニックネームを設定します。
- activity_main.xmlを開いてください。
- nickname_textテキストビューの中で、textプロパティを追加してください。以下のように、dataクラスのnicknameを言及してください。
android:text="@={myName.nickname}"
- MainActivity.ktの中のnicknameText.text = nicknameEdit.text.toString()の部分をmyName変数のnicknameをセットするためのコードに置き換えてください。
myName?.nickname = nicknameEdit.text.toString()
ニックネームが設定されたあとは、UIを新しいデータでリフレッシュするためのコードが必要です。そうするためには最新のデータによって再生成させるために、一度全てのデータバインディング文を無効にする必要があります。
- ニックネームのセットがされたあとにinvalidateAll()を追加してください。そうすることでUIが更新されたバインディングオブジェクトの値によってリフレッシュされます。
binding.apply {
myName?.nickname = nicknameEdit.text.toString()
invalidateAll()
...
}
- ビルドしてアプリを起動してください。以前と機能は変わっていません。
完成済みプロジェクト
完成済みプロジェクトは次のリンクからダウンロードできます。