データ バインディング ライブラリは、レイアウトの変数とビューへのアクセスに使用できるバインディング クラスを生成します。このドキュメントでは、生成されたバインディング クラスを作成してカスタマイズする方法を説明します。
生成されたバインディング クラスにより、レイアウト変数がレイアウト内のビューとリンクされます。バインディングの名前とパッケージはカスタマイズできます。生成されるすべてのバインディング クラスは ViewDataBinding
クラスを継承します。
バインディング クラスはレイアウト ファイルごとに生成されます。デフォルトでは、クラス名はパスカルケースに変換されたレイアウト ファイルの名前に Binding 接尾辞が付加されたものになります。たとえば、レイアウト ファイル名が activity_main.xml
の場合、生成されるクラスは ActivityMainBinding
になります。このクラスは、レイアウト プロパティからレイアウトのビューへのすべてのバインディングを保持し、バインディング式に値を割り当てる方法を認識します。
バインディング オブジェクトを作成する
バインディング オブジェクトは、レイアウトをインフレートした直後に作成され、レイアウト内の式を使用してビュー階層が変更される前にビュー階層が変更されることがないようにします。オブジェクトをレイアウトにバインドする最も一般的な方法は、バインディング クラスで静的メソッドを使用することです。次の例に示すように、バインディング クラスの inflate()
メソッドを使用して、ビュー階層をインフレートしてオブジェクトをバインドできます。
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val binding: MyLayoutBinding = MyLayoutBinding.inflate(layoutInflater) setContentView(binding.root) }
Java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater()); setContentView(binding.root); }
inflate()
メソッドの代替バージョンとして、LayoutInflater
オブジェクトのほかに ViewGroup
オブジェクトを受け取ることもできます。次の例をご覧ください。
Kotlin
val binding: MyLayoutBinding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false)
Java
MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false);
別のメカニズムを使用してレイアウトをインフレートする場合は、次のように個別にバインドできます。
Kotlin
val binding: MyLayoutBinding = MyLayoutBinding.bind(viewRoot)
Java
MyLayoutBinding binding = MyLayoutBinding.bind(viewRoot);
バインディング タイプが事前にわからないこともあります。そのような場合は、次のコード スニペットに示すように、DataBindingUtil
クラスを使用してバインディングを作成できます。
Kotlin
val viewRoot = LayoutInflater.from(this).inflate(layoutId, parent, attachToParent) val binding: ViewDataBinding? = DataBindingUtil.bind(viewRoot)
Java
View viewRoot = LayoutInflater.from(this).inflate(layoutId, parent, attachToParent); ViewDataBinding binding = DataBindingUtil.bind(viewRoot);
Fragment
、ListView
、RecyclerView
アダプター内でデータ バインディング アイテムを使用する場合は、次のコードサンプルに示すように、バインディング クラスま��は DataBindingUtil
クラスの inflate()
メソッドを使用することをおすすめします。
Kotlin
val listItemBinding = ListItemBinding.inflate(layoutInflater, viewGroup, false) // or val listItemBinding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false)
Java
ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false); // or ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);
ID 付きのビュー
データ バインディング ライブラリは、レイアウト内で ID を持つ各ビューのバインディング クラスに不変のフィールドを作成します。たとえば、データ バインディング ライブラリは、次のレイアウトから TextView
型の firstName
フィールドと lastName
フィールドを作成します。
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="user" type="com.example.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.firstName}"
android:id="@+id/firstName"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.lastName}"
android:id="@+id/lastName"/>
</LinearLayout>
</layout>
ライブラリは、ID を含むビューを単一のパスのビュー階層から抽出します。このメカニズムは、レイアウト内のすべてのビューに findViewById()
メソッドを呼び出すよりも効率的です。
ID はデータ バインディングがないほど必要ではありませんが、コードからビューへのアクセスが必要なケースもあります。
変数
データ バインディング ライブラリは、レイアウトで宣言された変数ごとにアクセサ メソッドを生成します。たとえば次のレイアウトでは、user
変数、image
変数、note
変数のセッター メソッドとゲッター メソッドがバインディング クラスに生成されます。
<data>
<import type="android.graphics.drawable.Drawable"/>
<variable name="user" type="com.example.User"/>
<variable name="image" type="Drawable"/>
<variable name="note" type="String"/>
</data>
ViewStub
通常のビューとは異なり、ViewStub
オブジェクトは非表示のビューとして開始されます。それらが表示されるか、明示的にインフレートされると、別のレイアウトをインフレートしてレイアウト内で自身を置き換えます。
ViewStub
はビュー階層に表示されなくなるため、バインディング オブジェクトのビューも非表示にして、ガベージ コレクションで要求できるようにする必要があります。ビューは最終ビューであるため、ViewStubProxy
オブジェクトが、生成されたバインディング クラスの ViewStub
の代わりになり、ViewStub
が存在する場合はそれにアクセスでき、ViewStub
がインフレートされるときはインフレートされたビュー階層にアクセスできます。
別のレイアウトをインフレートする場合は、新しいレイアウトのバインディングを設定する必要があります。したがって、ViewStubProxy
は ViewStub
OnInflateListener
をリッスンし、必要に応じてバインディングを確立する必要があります。リスナーは同時に 1 つしか存在できないため、ViewStubProxy
ではバインディングを確立した後に呼び出す OnInflateListener
を設定できます。
即時バインディング
変数または監視可能なオブジェクトが変更されると、次のフレームの前に変更するようにバインディングがスケジュールされます。ただし、バインディングをすぐに実行しなければならない場合もあります。強制的に実行するには、executePendingBindings()
メソッドを使用します。
動的変数
特定のバインディング クラスが不明な場合もあります。たとえば、任意のレイアウトに対して動作する RecyclerView.Adapter
は、特定のバインディング クラスを認識しません。onBindViewHolder()
メソッドの呼び出し中にバインディング値を割り当てる必要があります。
次の例では、RecyclerView
がバインドするすべてのレイアウトに item
変数があります。BindingHolder
オブジェクトには、ViewDataBinding
基本クラスを返す getBinding()
メソッドがあります。
Kotlin
override fun onBindViewHolder(holder: BindingHolder, position: Int) { item: T = items.get(position) holder.binding.setVariable(BR.item, item); holder.binding.executePendingBindings(); }
Java
public void onBindViewHolder(BindingHolder holder, int position) { final T item = items.get(position); holder.getBinding().setVariable(BR.item, item); holder.getBinding().executePendingBindings(); }
バックグラウンド スレッド
データモデルは、コレクションでない限り、バックグラウンド スレッドで変更できます。データ バインディングでは、同時実行の問題を回避するために、評価中に各変数またはフィールドがローカライズされます。
カスタムのバインディング クラスの名前
デフォルトでは、バインディング クラスはレイアウト ファイルの名前に基づいて生成されます。この名前が大文字で始まり、アンダースコア(_)が削除され、その後に続く文字が大文字にされ、語尾に Binding が付加されます。たとえば、レイアウト ファイル contact_item.xml
は ContactItemBinding
クラスを生成します。クラス���、モ���ュール パッケージの下の databinding
パッケージに配置されます。たとえば、モジュール パッケージが com.example.my.app
の場合、バインディング クラスは com.example.my.app.databinding
パッケージに配置されます。
data
要素の class
属性を調整することで、バインディング クラスの名前を変更したり、別のパッケージに配置したりできます。たとえば次のレイアウトでは、現在のモジュールの databinding
パッケージに ContactItem
バインディング クラスが生成されます。
<data class="ContactItem">
...
</data>
クラス名の前にピリオドを付けると、別のパッケージにバインディング クラスを生成できます。次の例では、モジュール パッケージ内にバインディング クラスを生成します。
<data class=".ContactItem">
...
</data>
バインディング クラスを生成する完全なパッケージ名を使用することもできます。次の例では、com.example
パッケージに ContactItem
バインディング クラスを作成します。
<data class="com.example.ContactItem">
...
</data>
参考情報
データ バインディングの詳細については、以下の参考情報をご覧ください。
あなたへのおすすめ
- 注: JavaScript がオフになっている場合はリンクテキストが表示されます
- レイアウトとバインディング式
- データ バインディング ライブラリ
- ビュー バインディング