オブザーバビリティとは、オブジェクトが データを変更できます。データ バインディング ライブラリを使用すると、 コレクションのオブジェクトです。
データ バインディングには任意のオブジェクトを使用できるが、オブジェクトを変更しても UI が更新されます。データ バインディングを使用すると、データに 他のオブジェクト(リスナー)に、通知を送信したときに 制御できるようになります。監視可能なクラスには次の 3 種類があります。 フィールド、コレクション、 オブジェクト。
監視可能なデータ オブジェクトのいずれかが UI と データ オブジェクトが変更されると、UI が自動的に更新されます。
監視可能なフィールド
クラスのプロパティが数件しかない場合、
実装するクラスを作成する
Observable インターフェース。この
汎用の Observable クラスと、
プリミティブ固有のクラスを使用して、フィールドを監視できるようにします。
ObservableBooleanObservableByteObservableCharObservableShortObservableIntObservableLongObservableFloatObservableDoubleObservableParcelable
監視可能フィールドは、自己完結型の監視可能なオブジェクトで、
表示されます。プリミティブ バージョンでは、アクセス中のボックス化とボックス化解除を回避できる
必要があります。このメカニズムを使用するには、Java で public final プロパティを作成します。
または読み取り専用のプロパティを使用します。
次の例をご覧ください。
Kotlin
class User { val firstName = ObservableField<String>() val lastName = ObservableField<String>() val age = ObservableInt() }
Java
private static class User { public final ObservableField<String> firstName = new ObservableField<>(); public final ObservableField<String> lastName = new ObservableField<>(); public final ObservableInt age = new ObservableInt(); }
フィールドの値にアクセスするには、
set()、
get() アクセサ メソッド
または、Kotlin プロパティを使用
構文:
Kotlin
user.firstName = "Google" val age = user.age
Java
user.firstName.set("Google"); int age = user.age.get();
監視可能なコレクション
アプリによっては、データを保持するために動的な構造を使用することがあります。監視可能なコレクションを使用すると
キーを使用してこれらの構造にアクセスできるようにします。「
ObservableArrayMap クラス
が有用であるのは、キーが String などの参照型である場合です。
次の例をご覧ください。
Kotlin
ObservableArrayMap<String, Any>().apply { put("firstName", "Google") put("lastName", "Inc.") put("age", 17) }
Java
ObservableArrayMap<String, Object> user = new ObservableArrayMap<>(); user.put("firstName", "Google"); user.put("lastName", "Inc."); user.put("age", 17);
レイアウトでは、 次の例をご覧ください。
<data>
    <import type="android.databinding.ObservableMap"/>
    <variable name="user" type="ObservableMap<String, Object>"/>
</data>
…
<TextView
    android:text="@{user.lastName}"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
<TextView
    android:text="@{String.valueOf(1 + (Integer)user.age)}"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
ObservableArrayList
クラスは、次のようにキーが整数の場合に役立ちます。
Kotlin
ObservableArrayList<Any>().apply { add("Google") add("Inc.") add(17) }
Java
ObservableArrayList<Object> user = new ObservableArrayList<>(); user.add("Google"); user.add("Inc."); user.add(17);
このレイアウトでは、 次の例をご覧ください。
<data>
    <import type="android.databinding.ObservableList"/>
    <import type="com.example.my.app.Fields"/>
    <variable name="user" type="ObservableList<Object>"/>
</data>
…
<TextView
    android:text='@{user[Fields.LAST_NAME]}'
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
<TextView
    android:text='@{String.valueOf(1 + (Integer)user[Fields.AGE])}'
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>
監視可能なオブジェクト
Observable インターフェースを実装するクラスを使用すると、
プロパティの変更について通知を受け取りたいリスナー。
渡されます。
Observable インターフェースにはリスナーを追加および削除するメカニズムがありますが、
通知を送信するタイミングを指定できます。開発を容易にするために、Data API は
バインディング ライブラリは、
BaseObservable クラスは、
リスナー登録メカニズムを実装します。実装するデータクラスは、
BaseObservable は、プロパティが変更されたときに通知します。タスク
Bindable アノテーションを
ゲッターに送り、
notifyPropertyChanged()
メソッドに追加します。
Kotlin
class User : BaseObservable() { @get:Bindable var firstName: String = "" set(value) { field = value notifyPropertyChanged(BR.firstName) } @get:Bindable var lastName: String = "" set(value) { field = value notifyPropertyChanged(BR.lastName) } }
Java
private static class User extends BaseObservable { private String firstName; private String lastName; @Bindable public String getFirstName() { return this.firstName; } @Bindable public String getLastName() { return this.lastName; } public void setFirstName(String firstName) { this.firstName = firstName; notifyPropertyChanged(BR.firstName); } public void setLastName(String lastName) { this.lastName = lastName; notifyPropertyChanged(BR.lastName); } }
データ バインディングは、モジュール パッケージ内に BR という名前のクラスを生成します。このクラスには、
データ バインディングに使用されるリソースの ID。Bindable アノテーション
コンパイル時に、BR クラスファイルにエントリを生成します。基本クラスが
データクラスは変更できないため、Observable インターフェースを実装できます。
使用
PropertyChangeRegistry
リスナーの登録と通知を効率的に行うことができます。
ライフサイクル対応オブジェクト
アプリのレイアウトは、データ バインディング ソースに自動的にバインドされ、 データの変更を UI に通知します。これにより、バインディングが UI が画面に表示されたときにのみトリガーされます。
データ バインディングのサポート
StateFlow、
LiveData。詳細については、このモジュールの
データ バインディングで LiveData を使用する方法については、LiveData を使用して UI にデータを通知するをご覧ください。
あります。
StateFlow を使用する
アプリで Kotlin とコルーチンを使用する場合は、次を使用できます。
データ バインディング ソースとして StateFlow オブジェクトを指定します。StateFlow オブジェクトを次の環境で使用する場合:
ライフサイクル オーナーを指定して、スコープのスコープを
StateFlow オブジェクト。次の例では、アクティビティを
バインディング クラスがインスタンス化された後のライフサイクル オーナーに保持されます。
class ViewModelActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        // Inflate view and obtain an instance of the binding class.
        val binding: UserBinding = DataBindingUtil.setContentView(this, R.layout.user)
        // Specify the current activity as the lifecycle owner.
        binding.lifecycleOwner = this
    }
}
レイアウト ビューをアーキテクチャにバインドする
コンポーネント、データ バインディング
ViewModel とシームレスに連携
説明します。次のように StateFlow と ViewModel を組み合わせて使用できます。
class ScheduleViewModel : ViewModel() {
    private val _username = MutableStateFlow<String>("")
    val username: StateFlow<String> = _username
    init {
        viewModelScope.launch {
            _username.value = Repository.loadUserName()
        }
    }
}
レイアウト内で、ViewModel オブジェクトのプロパティとメソッドを
対応するビューを、以下のようにバインディング式を使用して
例:
<TextView
    android:id="@+id/name"
    android:text="@{viewmodel.username}" />
ユーザー名の値が変更されるたびに、UI が自動的に更新されます。
StateFlow サポートを無効にする
Kotlin と AndroidX を使用するアプリでは、StateFlow のサポートが自動的に有効になります。
データ バインディングに含まれるデータです。つまり、コルーチンの依存関係は
自動的にアプリに追加されます。
この機能を無効にするには、次のコードを
build.gradle ファイル:
Groovy
android { ... dataBinding { addKtx = false } }
Kotlin
android { ... dataBinding { addKtx = false } }
または、次を追加して、プロジェクトで StateFlow をグローバルに無効にすることもできます。
次の行を gradle.properties ファイルに追加します。
Groovy
android.defaults.databinding.addKtx = false
Kotlin
android.defaults.databinding.addKtx = false
参考情報
データ バインディングについて詳しくは、以下の参考情報をご覧ください。
サンプル
Codelab
ブログ投稿
あなたへのおすすめ
- 注: JavaScript がオフになっている場合はリンクテキストが表示されます
 - ViewModel の保存済み状態のモジュール
 - レイアウト ビューをアーキテクチャ コンポーネントにバインドする
 - ページング ライブラリの概要