式言語を使用すると、ディスパッチされたイベントを処理する式を記述できます。 視聴回数で表します。データ バインディング ライブラリは、必要なクラスを を使用して、レイアウト内のビューをデータ オブジェクトをバインドします。
データ バインディングのレイアウト ファイルは若干異なり、次のルートタグで始まります。
layout
の後に data
要素と view
ルート要素が続きます。このビュー
要素は、バインディングのないレイアウト ファイル内のルート要素です。次のコードでは、
に、サンプルのレイアウト ファイルを示します。
<?xml version="1.0" encoding="utf-8"?>
<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}"/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.lastName}"/>
</LinearLayout>
</layout>
data
内の user
変数は、内部で使用できるプロパティを表します。
このレイアウトは
<variable name="user" type="com.example.User" />
レイアウト内の式は、
@{}
構文。次の例では、
TextView
テキストは
user
変数の firstName
プロパティ:
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.firstName}" />
データ オブジェクト
User
エンティティを記述するプレーン オブジェクトがあるとします。
Kotlin
data class User(val firstName: String, val lastName: String)
Java
public class User { public final String firstName; public final String lastName; public User(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } }
この型のオブジェクトには、変更されることがないデータが格納されます。一般的に、アプリでは 一度読み取られ、その後変更されないデータですまた、kubectl の たとえば、 Java プログラミング言語で利用できます。
Kotlin
// Not applicable in Kotlin. data class User(val firstName: String, val lastName: String)
Java
public class User { private final String firstName; private final String lastName; public User(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } public String getFirstName() { return this.firstName; } public String getLastName() { return this.lastName; } }
データ バインディングの観点からすると、これら 2 つのクラスは同等です。「
次に使用される式 @{user.firstName}
android:text
属性は、前のクラスの firstName
フィールドにアクセスし、
getFirstName()
メソッドを使用します。また、
firstName()
(メソッドが存在する場合)。
データのバインド
バインディング クラスはレイアウト ファイルごとに生成されます。デフォルトでは、
クラスは、パスカルケースに変換されたレイアウト ファイルの名前に基づいており、
Binding サフィックスが追加されます。たとえば、上のレイアウト ファイル名は、
activity_main.xml
。対応する生成されるバインディング クラス:
ActivityMainBinding
。
このクラスは、レイアウト プロパティのすべてのバインディングを保持します。たとえば、
user
変数(レイアウトのビューに割り当て、値の割り当て方法がわかっているもの)
バインディング式を指定しますインフレート中にバインディングを作成することをおすすめします。
配置する必要があります。
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val binding: ActivityMainBinding = DataBindingUtil.setContentView( this, R.layout.activity_main) binding.user = User("Test", "User") }
Java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main); User user = new User("Test", "User"); binding.setUser(user); }
実行時に、アプリの UI に Test ユーザーが表示されます。別の方法として、
使用してビューを取得
LayoutInflater
:
次の例をご覧ください。
Kotlin
val binding: ActivityMainBinding = ActivityMainBinding.inflate(getLayoutInflater())
Java
ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater());
データ バインディング アイテムを
Fragment
ListView
、または
RecyclerView
使用する場合は、
inflate()
バインディング クラスのメソッド、または
DataBindingUtil
クラスを
次のコードサンプルをご覧ください。
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);
式言語
一般的な機能
式言語はマネージコードの式によく似ています。マイページ 式言語で次の演算子とキーワードを使用できます。
- 数学:
+ - / * %
- 文字列の連結:
+
- 論理:
&& ||
- バイナリ:
& | ^
- 単項:
+ - ! ~
- シフト:
>> >>> <<
- 比較:
== > < >= <=
(<
は<
としてエスケープする必要があります) instanceof
- グループ:
()
- リテラル(文字、文字列、数値、
null
など) - キャスト
- メソッド呼び出し
- フィールド アクセス
- 配列アクセス:
[]
- 3 項演算子:
?:
次に例を示します。
android:text="@{String.valueOf(index + 1)}"
android:visibility="@{age > 13 ? View.GONE : View.VISIBLE}"
android:transitionName='@{"image_" + id}'
使用できない演算
使用可能な式の構文に、次の演算がありません マネージド・コードで:
this
super
new
- 明示的な汎用呼び出し
null 合体演算子
null 合体演算子(??
)が null
でない場合、左のオペランドを選択します
前者が null
の場合は右になります。
android:text="@{user.displayName ?? user.lastName}"
これは機能的に以下と同等です。
android:text="@{user.displayName != null ? user.displayName : user.lastName}"
プロパティ参照
式は、次の形式を使用してクラス内のプロパティを参照できます。
これはフィールド、ゲッター、
ObservableField
オブジェクト:
android:text="@{user.lastName}"
null ポインタ例外を回避する
生成されたデータ バインディング コードは null
値を自動的にチェックし、
null ポインタ例外。たとえば、式 @{user.name}
で、
user
が null の場合、user.name
にはデフォルト値の null
が割り当てられます。もし
参照 user.age
(age が int
型)の場合、データ バインディングでは
0
に設定されます。
ビューの参照
式は、以下を使用して ID でレイアウト内の他のビューを参照できます。 構文:
android:text="@{exampleText.text}"
次の例では、TextView
ビューが次の EditText
ビューを参照しています。
行います。
<EditText
android:id="@+id/example_text"
android:layout_height="wrap_content"
android:layout_width="match_parent"/>
<TextView
android:id="@+id/example_output"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{exampleText.text}"/>
コレクション
配列、リスト、スパース リスト、
便宜上 []
演算子を使用します。
<data>
<import type="android.util.SparseArray"/>
<import type="java.util.Map"/>
<import type="java.util.List"/>
<variable name="list" type="List<String>"/>
<variable name="sparse" type="SparseArray<String>"/>
<variable name="map" type="Map<String, String>"/>
<variable name="index" type="int"/>
<variable name="key" type="String"/>
</data>
...
android:text="@{list[index]}"
...
android:text="@{sparse[index]}"
...
android:text="@{map[key]}"
object.key
表記を使用して、マップの値を参照することもできます。対象
たとえば、上記の例の @{map[key]}
を
@{map.key}
。
文字列リテラル
属性値を単一引用符で囲むと、 二重引用符で囲む必要があります。
android:text='@{map["firstName"]}'
二重引用符で属性値を囲むこともできます。その際、
次に示すように、文字列リテラルはバッククォート `
で囲む必要があります。
こちらをご覧ください。
android:text="@{map[`firstName`]}"
リソース
次の構文により、式でアプリのリソースを参照できます。
android:padding="@{large? @dimen/largePadding : @dimen/smallPadding}"
パラメータを指定することにより、書式設定文字列と複数形を評価できます。
android:text="@{@string/nameFormat(firstName, lastName)}"
android:text="@{@plurals/banana(bananaCount)}"
プロパティ参照とビュー リソース パラメータとして渡す参照:
android:text="@{@string/example_resource(user.lastName, exampleText.text)}"
複数形が複数のパラメータを取る場合は、すべてのパラメータを渡します。
Have an orange
Have %d oranges
android:text="@{@plurals/orange(orangeCount, orangeCount)}"
一部のリソースでは、次に示すように、明示的な型の評価が必要です。 table:
タイプ | 通常の参照 | 式参照 |
---|---|---|
String[] |
@array |
@stringArray |
int[] |
@array |
@intArray |
TypedArray |
@array |
@typedArray |
Animator |
@animator |
@animator |
StateListAnimator |
@animator |
@stateListAnimator |
color int |
@color |
@color |
ColorStateList |
@color |
@colorStateList |
イベント処理
データ バインディングを使用すると、イベントを処理する式を記述して、
ビュー(たとえば、
onClick()
メソッドを呼び出します。イベント属性名は、リスナー メソッドの名前によって決定されます。
いくつか例外がありますたとえば
View.OnClickListener
の例:
メソッド onClick()
なので、このイベントの属性は android:onClick
です。
クリック イベント専用のイベント ハンドラがいくつかあり、
android:onClick
以外の属性を指定することをおすすめします。こちらの
次の属性を追加して、この種の競合を回避してください。
クラス | リスナーのセッター | 属性 |
---|---|---|
SearchView |
setOnSearchClickListener(View.OnClickListener) |
android:onSearchClick |
ZoomControls |
setOnZoomInClickListener(View.OnClickListener) |
android:onZoomIn |
ZoomControls |
setOnZoomOutClickListener(View.OnClickListener) |
android:onZoomOut |
この 2 つのメカニズムを使用できます。詳細については、 イベントを処理します。
- メソッド参照: 式では、
リスナー メソッドのシグネチャに適合する参照メソッドが含まれます。日時
式はメソッド参照として評価され、データ バインディングによってメソッドがラップされる
オーナー オブジェクトを参照し、そのリスナーを
ターゲット ビューです。式が
null
と評価された場合、データ バインディングは実行されません。 代わりにリスナーを作成し、null
リスナーを設定してください。 - リスナー バインディング: リスナー バインディング イベント発生時に評価されますデータ バインディングでは常に、 ビューに設定します。イベントがディスパッチされると、 リスナーはラムダ式を評価します。
メソッド参照
他の処理と同様に、イベントをハンドラ メソッドに直接バインドできます。
割り当て
android:onClick
を
メソッドを呼び出せますGoogle Workspace の
View
onClick
属性は、
コンパイル時に処理されます。そのため、このメソッドが存在しない場合や、
コンパイル時エラーが発生します。
メソッド参照とリスナー バインディングの主な違いは、 実際のリスナーの実装は、データがバインドされた時点で作成され、 イベントがトリガーされます。イベントが発生したときに式を評価したい場合は、 リスナー バインディングを使用してください。
イベントをそのハンドラに割り当てるには、通常のバインディング式を使用して、 value は呼び出すメソッド名です。たとえば、次の例をご覧ください。 レイアウト データ オブジェクト:
Kotlin
class MyHandlers { fun onClickFriend(view: View) { ... } }
Java
public class MyHandlers { public void onClickFriend(View view) { ... } }
バインディング式では、ビューのクリック リスナーを
onClickFriend()
メソッドを次のように指定します。
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="handlers" type="com.example.MyHandlers"/>
<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:onClick="@{handlers::onClickFriend}"/>
</LinearLayout>
</layout>
リスナー バインディング
リスナー バインディングは、イベントの発生時に実行されるバインディング式です。。 メソッド参照に似ていますが、任意のデータ バインディングを実行できる 表します。この機能は Gradle 用 Android Gradle プラグインで使用できます 使用できます。
メソッド参照では、メソッドのパラメータは、
イベントリスナー。リスナー バインディングでは、戻り値のみが
リスナーの期待される戻り値(void
が想定されている場合を除く)。対象
たとえば、onSaveClick()
がある次のプレゼンター クラスについて考えてみましょう。
メソッド:
Kotlin
class Presenter { fun onSaveClick(task: Task){} }
Java
public class Presenter { public void onSaveClick(Task task){} }
次のように、クリック イベントを onSaveClick()
メソッドにバインドできます。
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable name="task" type="com.android.example.Task" />
<variable name="presenter" type="com.android.example.Presenter" />
</data>
<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent">
<Button android:layout_width="wrap_content" android:layout_height="wrap_content"
android:onClick="@{() -> presenter.onSaveClick(task)}" />
</LinearLayout>
</layout>
式でコールバックを使用すると、データ バインディングによって自動的に それをイベントに登録します。ビューが イベントが発生すると、データ バインディングは指定された式を評価します。通常のバインディングと同じ null とスレッドの安全性を確保しながら、データ バインディングを 評価しています。
上記の例では、onClick(View)
に渡される view
パラメータは、
定義します。リスナー バインディングでは、リスナー パラメータに次の 2 つの選択肢があります。
メソッドのすべてのパラメータを無視することも、すべてのパラメータに名前を付けることもできます。ご希望の場合
パラメータに名前を付ける場合は、式で使用できます。たとえば、
上の式は次のように記述できます。
android:onClick="@{(view) -> presenter.onSaveClick(task)}"
パラメータを式で使用する場合は、次の操作を行います。
Kotlin
class Presenter { fun onSaveClick(view: View, task: Task){} }
Java
public class Presenter { public void onSaveClick(View view, Task task){} }
android:onClick="@{(theView) -> presenter.onSaveClick(theView, task)}"
また、ラムダ式と複数のパラメータを使用できます。
Kotlin
class Presenter { fun onCompletedChanged(task: Task, completed: Boolean){} }
Java
public class Presenter { public void onCompletedChanged(Task task, boolean completed){} }
<CheckBox android:layout_width="wrap_content" android:layout_height="wrap_content"
android:onCheckedChanged="@{(cb, isChecked) -> presenter.completeChanged(task, isChecked)}" />
リッスンしているイベントが void
以外の型の値を返す場合、
式も同じ型の値を返す必要があります。たとえば
感知して長押し(長押し)イベントがある場合、式は
ブール値を返します。
Kotlin
class Presenter { fun onLongClick(view: View, task: Task): Boolean { } }
Java
public class Presenter { public boolean onLongClick(View view, Task task) { } }
android:onLongClick="@{(theView) -> presenter.onLongClick(theView, task)}"
null
オブジェクトが原因で式を評価できない場合、データ バインディングは
その型のデフォルト値(参照型の null
、0
など)。
int
、または boolean
の場合は false
。
述語を含む式を使用する必要がある場合(例:
3 項表記—void
を記号として使用できます。
android:onClick="@{(v) -> v.isVisible() ? doSomething() : void}"
複雑なリスナーを使用しない
リスナー式は強力で、コードを読みやすくします。 一方、リスナーに複雑な式が含まれていると、レイアウトが難しくなります 管理する必要がありません。利用可能なデータを渡して式をシンプルに保つ コールバックメソッドに渡します内部にビジネス ロジックを実装する。 コールバック関数を呼び出します。
インポート、変数、インクルード
データ バインディング ライブラリには、インポート、変数、 含まれます。インポートにより、レイアウト ファイル内でクラスを参照しやすくなります。 変数を使用すると、バインディング式で使用できるプロパティを記述できます。 インクルードを使用すると、複雑なレイアウトをアプリ全体で再利用できます。
インポート
インポートを使用すると、マネージド コードと同様に、レイアウト ファイル内でクラスを参照できます。
data
要素内では、0 個以上の import
要素を使用できます。「
次のコード例では、View
クラスをレイアウト ファイルにインポートしています。
<data>
<import type="android.view.View"/>
</data>
View
クラスをインポートすると、バインディング式から参照できます。
次の例は、Terraform の
VISIBLE
、
View
クラスの GONE
定数:
<TextView
android:text="@{user.lastName}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="@{user.isAdult ? View.VISIBLE : View.GONE}"/>
型のエイリアス
クラス名が競合する場合は、いずれかのクラスの名前を
使用します。次の例では、View
クラスの名前を
com.example.real.estate
パッケージを Vista
に追加します。
<import type="android.view.View"/>
<import type="com.example.real.estate.View"
alias="Vista"/>
その後、Vista
を使用して com.example.real.estate.View
と View
を参照できます。
レイアウト ファイル内で android.view.View
を参照しています。
他のクラスをインポートする
インポートした型は、変数と式での型参照として使用できます。「
次の例では、変数の型として User
と List
が使用されています。
<data>
<import type="com.example.User"/>
<import type="java.util.List"/>
<variable name="user" type="User"/>
<variable name="userList" type="List<User>"/>
</data>
インポートされた型を使用して、式の一部をキャストできます。次の
この例では、connection
プロパティを User
の型にキャストしています。
<TextView
android:text="@{((User)(user.connection)).lastName}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
また、インポートされた型は、
表します。次のコードは、MyStringUtils
クラスをインポートして参照します。
capitalize
メソッドを使用します。
<data>
<import type="com.example.MyStringUtils"/>
<variable name="user" type="com.example.User"/>
</data>
…
<TextView
android:text="@{MyStringUtils.capitalize(user.lastName)}"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
マネージコードと同様に、java.lang.*
は自動的にインポートされます。
変数
data
要素内で複数の variable
要素を使用できます。各
variable
要素は、使用するレイアウトに設定できるプロパティを記述します。
レイアウト ファイル内のバインディング式で使用できます。次の例では、
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>
変数の型はコンパイル時に検査されるため、変数に
Observable
または
監視可能なコレクション
型に反映する必要があります。変数が基本クラスまたはインターフェースの場合
Observable
インターフェースを実装していないアプリの場合、変数は
表示されます。
さまざまな構成(たとえば、 横向き、縦向きなど)に応じて、変数が組み合わされます。重複しない 変数定義が競合する場合があるからです。
生成されるバインディング クラスには、記述された各要素のセッターとゲッターが
使用します。セッターまで、変数はマネージド コードのデフォルト値を取ります。
が呼び出されます。null
は参照タイプ、0
は int
、false
は
boolean
など
バインディング式で使用するために context
という名前の特殊な変数が生成されます。
できます。context
の値は、
Context
オブジェクト(ルートビューの
getContext()
メソッドを使用します。「
context
変数は、明示的な変数宣言によってオーバーライドされます。
表示されます。
インクルード
含まれるレイアウトのバインディングに、変数を渡すことができます。
属性でアプリの名前空間と変数名を使用して作成します。「
次の例では、name.xml
からインクルードされた user
変数と、
contact.xml
レイアウト ファイル:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto">
<data>
<variable name="user" type="com.example.User"/>
</data>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/name"
bind:user="@{user}"/>
<include layout="@layout/contact"
bind:user="@{user}"/>
</LinearLayout>
</layout>
データ バインディングでは、merge 要素の直接の子としての include はサポートされていません。 たとえば、次のレイアウトはサポートされていません。
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto">
<data>
<variable name="user" type="com.example.User"/>
</data>
<merge><!-- Doesn't work -->
<include layout="@layout/name"
bind:user="@{user}"/>
<include layout="@layout/contact"
bind:user="@{user}"/>
</merge>
</layout>
参考情報
データ バインディングについて詳しくは、以下の参考リンクをご覧ください。