פריסות וביטויים מקושרים

שפת הביטויים מאפשרת לכתוב ביטויים שמטפלים באירועים שנשלחים לפי צפיות. הספרייה לקישור נתונים יוצרת באופן אוטומטי את המחלקות הנדרשות כדי לקשר בין התצוגות בפריסה לבין האובייקטים של הנתונים.

קובצי הפריסה של קישור הנתונים שונים מעט ומתחילים בתג בסיס של layout, ואחריו רכיב data ורכיב בסיס (root) 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>

המשתנה user בתוך data מתאר מאפיין שאפשר להשתמש בו בתוך הפריסה הזו:

<variable name="user" type="com.example.User" />

ביטויים בתוך הפריסה נכתבים במאפייני המאפיינים באמצעות תחביר @{}. במשפט הבא, הטקסט TextView מוגדר המאפיין firstName של המשתנה user:

<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;
  }
}

לאובייקט הזה יש נתונים שלא משתנים. לעיתים קרובות יש באפליקציות נתונים שנקראים פעם אחת ולא משתנים לאחר מכן. אפשר גם להשתמש אובייקט שתואם לקבוצה של מוסכמות, כמו שימוש ב-methods של רכיב גישה בשפת התכנות 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;
  }
}

מבחינת קישור הנתונים, שתי הסוגים האלה מקבילות. ביטוי @{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);
}

בזמן הריצה, האפליקציה מציגה את המשתמש בשדה 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);

שפת הביטוי

תכונות נפוצות

שפת הביטויים דומה מאוד לביטויים שנמצאו בקוד מנוהל. שלך יכול להשתמש באופרטורים ובמילות המפתח הבאים בשפת הביטוי:

  • מתמטיקה: + - / * %
  • שרשור מחרוזות: +
  • לוגי: && ||
  • בינארי: & | ^
  • אונרית: + - ! ~
  • Shift: >> >>> <<
  • השוואה: == > < >= <= (צריך לסמן את ה-< בתו בריחה (escape) בתור &lt;)
  • instanceof
  • קיבוץ: ()
  • מילים, כמו תו, מחרוזת, ספרות, null
  • העברה
  • קריאות לשיטות
  • גישה לשדה
  • גישה למערך: []
  • אופרטור תלת-ממדי: ?:

הנה כמה דוגמאות:

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, כאשר הגיל הוא מסוג int, אז קישור הנתונים משתמש ערך ברירת המחדל של 0.

הצגת הפניות

ביטוי יכול להפנות לתצוגות אחרות בפריסה לפי מזהה, באמצעות הפקודה הבאה: תחביר:

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}"/>

אוספים

אפשר לגשת לאוספים נפוצים, כמו מערכים, רשימות, רשימות מעטות ו מפות Google בעזרת האופרטור [], לנוחותך.

<data>
    <import type="android.util.SparseArray"/>
    <import type="java.util.Map"/>
    <import type="java.util.List"/>
    <variable name="list" type="List&lt;String>"/>
    <variable name="sparse" type="SparseArray&lt;String>"/>
    <variable name="map" type="Map&lt;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)}"

משאבים מסוימים מחייבים הערכה מפורשת של סוגים, כפי שמוצג בהמשך טבלה:

סוג הפניה רגילה הפנייה לביטוי
String[] @array @stringArray
int[] @array @intArray
TypedArray @array @typedArray
Animator @animator @animator
StateListAnimator @animator @stateListAnimator
color int @color @color
ColorStateList @color @colorStateList

טיפול באירועים

קישור נתונים מאפשר לך לכתוב אירועים הקשורים לביטויים שנשלחים מ- את הצפיות. לדוגמה onClick() . שמות מאפייני אירועים נקבעים לפי השם של שיטת ה-listener, עם כמה יוצאים מן הכלל. לדוגמה, ל-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

ניתן להשתמש בשני המנגנונים האלה, המתוארים בפירוט בקטעים אחרי, כדי לטפל באירוע:

  • הפניות שיטות: בביטויים אפשר להגדיר שיטות עזר שתואמות לחתימה של שיטת ה-listener. מתי ביטוי שהערך שלו הוא הפניה לשיטה, קישור נתונים אורז את השיטה ואובייקט של בעלים ב-listener ומגדיר את ה-listener תצוגת יעד. אם הערך של הביטוי הוא null, קישור הנתונים לא ליצור אוזן null ולהגדיר אוזן null במקום זאת.
  • קישורי האזנה: ביטויים מסוג lambda מוערכים כשהאירוע מתרחש. קישור הנתונים תמיד יוצר להקשיב, שאותו הוא מגדיר בתצוגה. כשהאירוע נשלח, המאזין מעריך את ביטוי lambda.

הפניות ל-method

אפשר לקשר אירועים ישירות ל-methods של handler, בדומה לאופן שבו אפשר להקצות android:onClick אל ה-method בפעילות. יתרון אחד בהשוואה המאפיין View onClick הוא מעובד בזמן הידור (compile). כך שאם השיטה לא קיימת, החתימה לא נכונה, תקבלו שגיאה של זמן הידור.

ההבדל העיקרי בין הפניות שיטות לקישורי האזנה הוא הטמעת ה-listener בפועל נוצרת כשהנתונים כפופים, ולא כשה מופעל. אם אתם מעדיפים להעריך את הביטוי כשהאירוע במקרה כזה, צריך להשתמש בקישורי האזנה.

כדי להקצות אירוע ל-handler שלו, צריך להשתמש בביטוי קישור רגיל, עם הפרמטר הוא שם ה-method לקריאה. למשל, נבחן את הדוגמה הבאה פריסת אובייקט נתונים:

Kotlin

class MyHandlers {
    fun onClickFriend(view: View) { ... }
}

Java

public class MyHandlers {
    public void onClickFriend(View view) { ... }
}

ביטוי הקישור יכול להקצות את ה-click Listener לצפייה 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>

קישורי האזנה

קישורי האזנה הם ביטויים מקושרים שפועלים כשמתרחש אירוע. הם דומות להפניות לשיטות, אבל הן מאפשרות להריץ קישור נתונים שרירותי הבעות פנים. התכונה הזו זמינה בפלאגין Android Gradle ל-Gradle גרסה 2.0 ואילך.

בהפניות שיטות, הפרמטרים של השיטה חייבים להתאים לפרמטרים של the event listener. בקישורי האזנה, רק הערך המוחזר חייב להתאים הערך המוחזר הצפוי של ה-listen, אלא אם הוא צפוי להיות void. עבור לדוגמה, נבחן את קטגוריית המציג הבאה שיש לה onSaveClick() method:

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>

כשמשתמשים בקריאה חוזרת (callback) בביטוי, קישור הנתונים יוצר באופן אוטומטי את להקשיב הנדרש, ורושם אותו לאירוע. כאשר התצוגה מפעילה את אירוע, קישור נתונים מעריך את הביטוי הנתון. כמו בקישור רגיל מקבלים את ערך ה-null ו-thread בטוח לקישורי נתונים בזמן ביטויי המאזינים נבדקים.

בדוגמה שלמעלה, הפרמטר view שמועבר אל onClick(View) לא מוגדרת. קישורי ה-האזנה מספקים שתי אפשרויות לפרמטרים של ה-listen: אפשר להתעלם מכל הפרמטרים של השיטה או לתת שם לכולם. אם אתם מעדיפים כדי לתת שמות לפרמטרים, אפשר להשתמש בהם בביטוי. לדוגמה, הוא יכול לכתוב את הביטוי הקודם באופן הבא:

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)}"

בנוסף, ניתן להשתמש בביטוי lambda עם יותר מפרמטר אחד:

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 או false למשך boolean.

אם אתם צריכים להשתמש בביטוי עם פרדיקט, לדוגמה, ternary - ניתן להשתמש ב-void כסמל:

android:onClick="@{(v) -> v.isVisible() ? doSomething() : void}"

הימנעות מפונקציות מאזינים מורכבות

ביטויי האזנה הם עוצמתיים ויכולים להקל על הקריאה של הקוד. ב מצד שני, פונקציות מאזינים שמכילות ביטויים מורכבים הופכים את הפריסה לקשה יותר לקריאה ולתחזוקה. שומרים על ביטויים פשוטים כמו העברת נתונים זמינים מממשק המשתמש לשיטת הקריאה החוזרת (callback). להטמיע כל לוגיקה עסקית שיטת הקריאה החוזרת (callback) שאתם מפעילים מהביטוי של המאזינים.

ייבוא, משתנים וכולל

הספרייה לקישור נתונים מספקת תכונות כמו ייבוא, משתנים כוללת. לאחר הייבוא, קל להפנות למחלקות בתוך קובצי הפריסה. משתנים מאפשרים לתאר נכס שאפשר להשתמש בו בביטויים מקושרים. התכונה הזו מאפשרת לך לעשות שימוש חוזר בפריסות מורכבות בכל האפליקציה.

ייבוא

ייבוא מאפשר להפנות למחלקות בתוך קובץ הפריסה, למשל בקוד מנוהל. ניתן להשתמש באפס רכיבי import או יותר בתוך הרכיב data. הקוד הבא מייבאת את המחלקה View לקובץ הפריסה:

<data>
    <import type="android.view.View"/>
</data>

ייבוא המחלקה View מאפשר להפנות אליה מהביטויים המקשרים. הדוגמה הבאה מראה איך להפנות אל VISIBLE ו- GONE קבועים של המחלקה View:

<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&lt;User>"/>
</data>

אפשר להשתמש בסוגים המיובאים כדי להפעיל Cast של חלק מביטוי. הבאים הדוגמה ממירה את המאפיין connection לסוג של User:

<TextView
   android:text="@{((User)(user.connection)).lastName}"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"/>

ניתן גם להשתמש בסוגים מיובאים כהתייחסות לשדות סטטיים ול-methods ב- הבעות פנים. הקוד הבא מייבא את המחלקה 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.* מיובא באופן אוטומטי.

משתנים

אפשר להשתמש במספר רכיבי variable בתוך הרכיב data. כל אחד הרכיב 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, המשתנים אינם שנמדד.

כשיש קובצי פריסה שונים להגדרות שונות (לדוגמה, לאורך או לרוחב), המשתנים משולבים. אסור הגדרות שונות של משתנים מתנגשים בין קובצי הפריסה האלה.

לסיווג הקישור שנוצר יש רכיב מגדיר (Setter) ומקבל (getter) עבור כל אחד מהמדדים שמתוארים משתנים. המשתנים לוקחים את ערכי ברירת המחדל של הקוד המנוהל עד שהרכיב קובע נקרא — null לסוגי קובצי העזר, 0 עבור int, false עבור boolean וכו'

משתנה מיוחד בשם context נוצר לשימוש בביטויים מקושרים לפי הצורך. הערך של context הוא אובייקט Context מתצוגת הרמה הבסיסית (root) getContext(). משתנה context בוטל על ידי הצהרה מפורשת של משתנה עם הפרמטר הזה שם.

כולל

אפשר להעביר משתנים לקישור של פריסה כלולה באמצעות מרחב השמות של האפליקציה ושם המשתנה במאפיין. בדוגמה הבאה מוצגים משתני user משולבים מ-name.xml 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>

קישור נתונים לא תומך בהכללה כצאצא ישיר של רכיב מיזוג. לדוגמה, הפריסה הבאה לא נתמכת:

<?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>

מקורות מידע נוספים

מידע נוסף על קישור נתונים זמין במקורות המידע הנוספים הבאים.

דוגמיות

שיעורי Lab

פוסטים בבלוגים