AndroidX ライブラリに含まれるアーキテクチャ コンポーネントを使用すると、堅牢でテストとメンテナンスが容易なアプリを設計できます。データ バインディング ライブラリはアーキテクチャ コンポーネントとシームレスに連携し、UI の開発をさらに簡素化します。アプリのレイアウトはアーキテクチャ コンポーネントのデータにバインドできます。これにより、UI コントローラ�����イ����イ�������管理し、データの変更を UI に通知できます。
このページでは、アーキテクチャ コンポーネントをアプリに組み込み、データ バインディング ライブラリを最大限に活用する方法について説明します。
LiveData を使用してデータの変更について UI に通知する
LiveData
オブジェクトをデータ バインディング ソースとして使用すると、データの変更について UI に自動的に通知できます。このアーキテクチャ コンポーネントについて詳しくは、LiveData の概要をご覧ください。
監視可能フィールドなどの Observable
を実装するオブジェクトとは異なり、LiveData
オブジェクトはデータ変更に登録されたオブザーバーのライフサイクルを認識しています。この知識には多くの利点があります。詳しくは LiveData を使用するメリットをご覧ください。Android Studio バージョン 3.1 以降では、データ バインディング コード内で監視可能なフィールドを LiveData
オブジェクトに置き換えることができます。
バインディング クラスで LiveData
オブジェクトを使用するには、ライフサイクル オーナーを指定して LiveData
オブジェクトのスコープを定義する必要があります。次の例では、バインディング クラスをインスタンス化した後、アクティビティをライフサイクル オーナーとして指定しています。
Kotlin
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.setLifecycleOwner(this) } }
Java
class ViewModelActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { // Inflate view and obtain an instance of the binding class. UserBinding binding = DataBindingUtil.setContentView(this, R.layout.user); // Specify the current activity as the lifecycle owner. binding.setLifecycleOwner(this); } }
次のセクションで説明するように、ViewModel
��ンポーネントを使用してデータをレイアウトにバインドできます。ViewModel
コンポーネントでは、LiveData
オブジェクトを使用してデータの変換や複数のデータソースの結合を行うことができます。次の例は、ViewModel
内のデータを変換する方法を示しています。
Kotlin
class ScheduleViewModel : ViewModel() { val userName: LiveDatainit { val result = Repository.userName userName = Transformations.map(result) { result -> result.value } } }
Java
class ScheduleViewModel extends ViewModel { LiveDatausername; public ScheduleViewModel() { String result = Repository.userName; userName = Transformations.map(result, result -> result.value); } }
ViewModel を使用して UI 関連のデータを管理する
データ バインディング ライブラリは ViewModel
コンポーネントとシームレスに連携します。ViewModel
は、レイアウトが監視してその変化に対応するデータを公開します。データ バインディング ライブラリで ViewModel
コンポーネントを使用すると、UI ロジックをレイアウトからコンポーネントに移動でき、テストが容易になります。必要に応じて、データ バインディング ライブラリにより、ビューがデータソースからバインドまたはバインド解除されるようにします。残りの作業のほとんどは、正しいデータが公開されていることを確認することです。このアーキテクチャ コンポーネントについて詳しくは、ViewModel の概要をご覧ください。
ViewModel
コンポーネントをデータ バインディング ライブラリで使用するには、ViewModel
クラスから継承したコンポーネントをインスタンス化し、バインディング クラスのインスタンスを取得して、ViewModel
コンポーネントをバインディング クラスのプロパティに割り当てる必要があります。次の例は、ライブラリでコンポーネントを使用する方法を示しています。
Kotlin
class ViewModelActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { // Obtain the ViewModel component. val userModel: UserModel by viewModels() // Inflate view and obtain an instance of the binding class. val binding: UserBinding = DataBindingUtil.setContentView(this, R.layout.user) // Assign the component to a property in the binding class. binding.viewmodel = userModel } }
Java
class ViewModelActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { // Obtain the ViewModel component. UserModel userModel = new ViewModelProvider(this).get(UserModel.class); // Inflate view and obtain an instance of the binding class. UserBinding binding = DataBindingUtil.setContentView(this, R.layout.user); // Assign the component to a property in the binding class. binding.viewmodel = userModel; } }
次の例に示すように、レイアウトでは、バインディング式を使用して ViewModel
コンポーネントのプロパティとメソッドを対応するビューに割り当てます。
<CheckBox
android:id="@+id/rememberMeCheckBox"
android:checked="@{viewmodel.rememberMe}"
android:onCheckedChanged="@{() -> viewmodel.rememberMeChanged()}" />
監視可能な ViewModel を使用して、バインディング アダプターを詳細に管理する
Observable
インターフェースを実装する ViewModel
コンポーネントを使用して、データの変更について他のアプリ コンポーネントに通知できます。LiveData
オブジェクトの使用方法と同様です。
LiveData
のライフサイクル管理機能が失われた場合でも、LiveData
オブジェクトを使用するよりも、Observable
インターフェースを実装する ViewModel
コンポーネントを使用することをおすすめします。Observable
を実装する ViewModel
コンポーネントを使用すると、アプリ内のバインディング アダプターをより詳細に制御できます。たとえば、このパターンでは、データが変更���れたときの通知をより細かく制御できます。また、カスタム メソッドを指定して、双方向データ バインディングの属性の値を設定することもできます。
監視可能な ViewModel
コンポーネントを実装するには、ViewModel
クラスから継承して Observable
インターフェースを実装するクラスを作成する必要があります。オブザーバーが addOnPropertyChangedCallback()
メソッドと removeOnPropertyChangedCallback()
メソッドを使用して通知を登録または登録解除するときに、カスタム ロジックを指定できます。notifyPropertyChanged()
メソッドでプロパティが変更されたときに実行されるカスタム ロジックを指定することもできます。次のコード例は、監視可能な ViewModel
を実装する方法を示しています。
Kotlin
/** * A ViewModel that is also an Observable, * to be used with the Data Binding Library. */ open class ObservableViewModel : ViewModel(), Observable { private val callbacks: PropertyChangeRegistry = PropertyChangeRegistry() override fun addOnPropertyChangedCallback( callback: Observable.OnPropertyChangedCallback) { callbacks.add(callback) } override fun removeOnPropertyChangedCallback( callback: Observable.OnPropertyChangedCallback) { callbacks.remove(callback) } /** * Notifies observers that all properties of this instance have changed. */ fun notifyChange() { callbacks.notifyCallbacks(this, 0, null) } /** * Notifies observers that a specific property has changed. The getter for the * property that changes must be marked with the @Bindable annotation to * generate a field in the BR class to be used as the fieldId parameter. * * @param fieldId The generated BR id for the Bindable field. */ fun notifyPropertyChanged(fieldId: Int) { callbacks.notifyCallbacks(this, fieldId, null) } }
Java
/** * A ViewModel that is also an Observable, * to be used with the Data Binding Library. */ class ObservableViewModel extends ViewModel implements Observable { private PropertyChangeRegistry callbacks = new PropertyChangeRegistry(); @Override protected void addOnPropertyChangedCallback( Observable.OnPropertyChangedCallback callback) { callbacks.add(callback); } @Override protected void removeOnPropertyChangedCallback( Observable.OnPropertyChangedCallback callback) { callbacks.remove(callback); } /** * Notifies observers that all properties of this instance have changed. */ void notifyChange() { callbacks.notifyCallbacks(this, 0, null); } /** * Notifies observers that a specific property has changed. The getter for the * property that changes must be marked with the @Bindable annotation to * generate a field in the BR class to be used as the fieldId parameter. * * @param fieldId The generated BR id for the Bindable field. */ void notifyPropertyChanged(int fieldId) { callbacks.notifyCallbacks(this, fieldId, null); } }
参考情報
データ バインディングの詳細については、次の参考情報をご覧ください。
あなたへのおすすめ
- 注: JavaScript がオフになっている場合はリンクテキストが表示されます
- 監視可能なデータ オブジェクトを操作する
- ページング データを読み込む、表示する
- ライフサイクル対応コンポーネントで Kotlin コルーチンを使用する