การออกแบบและการเชื่อมโยงนิพจน์

ภาษานิพจน์ช่วยให้คุณเขียนนิพจน์ที่จัดการเหตุการณ์ที่ส่งไป ตามจำนวนการดู ไลบรารีการเชื่อมโยงข้อมูลจะสร้างคลาสที่จำเป็นโดยอัตโนมัติ เพื่อเชื่อมโยงมุมมองในเลย์เอาต์กับออบเจ็กต์ข้อมูล

ไฟล์เลย์เอาต์การเชื่อมโยงข้อมูลจะแตกต่างกันเล็กน้อยและเริ่มต้นด้วยแท็กรากของ 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>

ตัวแปร 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;
  }
}

ออบเจ็กต์ประเภทนี้มีข้อมูลที่ไม่เคยเปลี่ยนแปลง เป็นเรื่องปกติในแอปที่ ข้อมูลที่อ่านเพียงครั้งเดียวและไม่มีการเปลี่ยนแปลงหลังจากนั้น นอกจากนี้คุณยังสามารถใช้ วัตถุที่เป็นไปตามชุดข้อตกลง เช่น การใช้เมธอดตัวเข้าถึงใน ภาษาการเขียนโปรแกรม 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() หากมีวิธีการดังกล่าว

การเชื่อมโยงข้อมูล

ระบบจะสร้างคลาสการเชื่อมโยงสำหรับไฟล์เลย์เอาต์แต่ละไฟล์ โดยค่าเริ่มต้น ชื่อของ จะอิงตามชื่อไฟล์เลย์เอาต์ที่แปลงเป็นตัวพิมพ์เล็ก/ใหญ่แบบ Pascal จะมีการเพิ่มคำต่อท้ายการเชื่อมโยงไว้ ตัวอย่างเช่น ชื่อไฟล์ของเลย์เอาต์ก่อนหน้าคือ 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 อีกวิธีหนึ่งคือ รับมุมมองโดยใช้ 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

android:text="@{user.displayName ?? user.lastName}"

ซึ่งมีฟังก์ชันการทำงานเทียบเท่ากับรายการต่อไปนี้

android:text="@{user.displayName != null ? user.displayName : user.lastName}"

การอ้างอิงพร็อพเพอร์ตี้

นิพจน์สามารถอ้างอิงพร็อพเพอร์ตี้ในคลาสได้โดยใช้รูปแบบต่อไปนี้ ซึ่งจะเหมือนกันสำหรับฟิลด์, Getters และ ObservableField ออบเจ็กต์มีดังนี้

android:text="@{user.lastName}"

หลีกเลี่ยงข้อยกเว้นตัวชี้ Null

โค้ดการเชื่อมโยงข้อมูลที่สร้างขึ้นจะตรวจสอบค่า null โดยอัตโนมัติและหลีกเลี่ยง ข้อยกเว้นตัวชี้ค่าว่าง ตัวอย่างเช่น ในนิพจน์ @{user.name} หาก user เป็นค่าว่าง 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}"/>

คอลเล็กชัน

คุณสามารถเข้าถึงคอลเล็กชันทั่วไป เช่น อาร์เรย์ รายการ รายการแบบกระจัดกระจาย และ แผนที่ โดยใช้โอเปอเรเตอร์ [] เพื่อความสะดวก

<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 เพื่อหลีกเลี่ยงข้อขัดแย้ง คุณสามารถใช้ ดังต่อไปนี้เพื่อหลีกเลี่ยงข้อขัดแย้งประเภทนี้

ชั้น ตัวตั้งค่า Listener แอตทริบิวต์
SearchView setOnSearchClickListener(View.OnClickListener) android:onSearchClick
ZoomControls setOnZoomInClickListener(View.OnClickListener) android:onZoomIn
ZoomControls setOnZoomOutClickListener(View.OnClickListener) android:onZoomOut

คุณสามารถใช้กลไก 2 ตัวนี้ได้ ซึ่งอธิบายไว้โดยละเอียดในส่วนที่ จัดการเหตุการณ์โดยทำดังนี้

  • การอ้างอิงเมธอด: ในนิพจน์ คุณสามารถ วิธีการอ้างอิงที่สอดคล้องกับลายเซ็นของเมธอด Listener วันและเวลา นิพจน์จะประเมินการอ้างอิงเมธอด การเชื่อมโยงข้อมูลจะรวมเมธอด การอ้างอิงและออบเจ็กต์เจ้าของใน Listener และกำหนด Listener นั้นในฟังก์ชัน มุมมองเป้าหมาย หากนิพจน์ประเมินเป็น null การเชื่อมโยงข้อมูลจะไม่ สร้าง Listener และตั้งค่า Listener null แทน
  • การเชื่อมโยง Listener: นิพจน์เหล่านี้คือนิพจน์แลมบ์ดาที่ จะได้รับการประเมินเมื่อเกิดเหตุการณ์ขึ้น การเชื่อมโยงข้อมูลจะสร้าง Listener ซึ่งตั้งค่าไว้ในมุมมอง เมื่อมีการส่งเหตุการณ์ พารามิเตอร์ Listener จะประเมินนิพจน์แลมบ์ดา

การอ้างอิงเมธอด

คุณสามารถเชื่อมโยงเหตุการณ์กับเมธอดเครื่องจัดการได้โดยตรง ซึ่งคล้ายกับวิธีที่คุณทำได้ กำหนด android:onClick เป็น ในกิจกรรม ข้อได้เปรียบหนึ่งข้อเทียบกับ View onClick แอตทริบิวต์คือ นิพจน์จะถูกประมวลผลในเวลาคอมไพล์ ดังนั้น ถ้าไม่พบเมธอดหรือ ลายเซ็นไม่ถูกต้อง คุณได้รับข้อผิดพลาดเกี่ยวกับเวลาคอมไพล์

ความแตกต่างสำคัญระหว่างการอ้างอิงเมธอดและการเชื่อมโยงผู้ฟังคือ การติดตั้งใช้งาน Listener จริงจะสร้างขึ้นเมื่อมีการเชื่อมโยงข้อมูล ไม่ใช่เมื่อมีการเชื่อมโยง ทริกเกอร์เหตุการณ์ หากต้องการประเมินนิพจน์เมื่อเหตุการณ์ ให้ใช้การเชื่อมโยงผู้ฟัง

หากต้องการกำหนดเหตุการณ์ให้กับเครื่องจัดการ ให้ใช้นิพจน์การเชื่อมโยงปกติที่มีพารามิเตอร์ ซึ่งเป็นชื่อเมธอดในการเรียก ตัวอย่างเช่น ลองพิจารณาตัวอย่างต่อไปนี้ ออบเจ็กต์ข้อมูลเลย์เอาต์:

Kotlin

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

Java

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

นิพจน์การเชื่อมโยงสามารถกำหนด 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>

การผูก Listener

การเชื่อมโยง Listener เป็นนิพจน์การเชื่อมโยงที่เรียกใช้เมื่อเหตุการณ์เกิดขึ้น โฆษณาเหล่านี้ คล้ายกับการอ้างอิงเมธอด แต่จะให้คุณเรียกใช้การเชื่อมโยงข้อมูลที่กำหนดเอง นิพจน์ ฟีเจอร์นี้ใช้ได้กับปลั๊กอิน Android Gradle สำหรับ Gradle เวอร์ชัน 2.0 ขึ้นไป

ในการอ้างอิงเมธอด พารามิเตอร์ของเมธอดจะต้องตรงกับพารามิเตอร์ของ Listener เหตุการณ์ ในการเชื่อมโยง Listener เฉพาะค่าผลลัพธ์เท่านั้นที่ต้องตรงกับ ผลลัพธ์ที่คาดไว้ของผู้ฟัง เว้นแต่ว่าจะคาดหวัง 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>

เมื่อมีการใช้ Callback ในนิพจน์ การเชื่อมโยงข้อมูลจะสร้างฟังก์ชัน Listener ที่จำเป็นและลงทะเบียนสำหรับกิจกรรมนั้น เมื่อมุมมองเริ่มทำงาน เหตุการณ์ การเชื่อมโยงข้อมูลจะประเมินนิพจน์ที่ระบุ เช่นเดียวกับการเชื่อมโยงปกติ นิพจน์ คุณจะได้รับความปลอดภัยแบบ Null และเทรดของการผูกข้อมูล ก็กำลังประเมินนิพจน์ของผู้ฟังอยู่

ในตัวอย่างก่อนหน้านี้ พารามิเตอร์ view ที่ส่งไปยัง onClick(View) ไม่ได้กำหนดไว้ การเชื่อมโยงผู้ฟังมี 2 ทางเลือกสำหรับพารามิเตอร์ Listener ได้แก่ คุณสามารถเพิกเฉยต่อพารามิเตอร์ทั้งหมดในเมธอดหรือตั้งชื่อพารามิเตอร์ทั้งหมดก็ได้ หากต้องการ เพื่อตั้งชื่อพารามิเตอร์ คุณสามารถใช้พารามิเตอร์ในนิพจน์ได้ ตัวอย่างเช่น คุณสามารถ สามารถเขียนนิพจน์ที่อยู่ก่อนหน้าดังนี้

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 ที่มีมากกว่า 1 พารามิเตอร์ได้ ดังนี้

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 ค่า นิพจน์จะต้องแสดงผลค่าประเภทเดียวกันด้วย ตัวอย่างเช่น ถ้าคุณต้องการ เพื่อฟังการสัมผัสและ Hold (คลิกยาว) นิพจน์จะต้องแสดงผลเป็น บูลีน

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

หากต้องการใช้นิพจน์ที่มีภาคแสดง เช่น สามส่วน คุณสามารถใช้ void เป็นสัญลักษณ์ได้ ดังนี้

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

หลีกเลี่ยงผู้ฟังที่ซับซ้อน

นิพจน์ของผู้ฟังมีประสิทธิภาพและทำให้โค้ดอ่านง่ายขึ้น ใน ในทางกลับกัน ผู้ฟังที่มีสีหน้าที่ซับซ้อนจะทำให้เลย์เอาต์ของคุณยากขึ้น ในการอ่านและดูแลรักษา ทำให้นิพจน์ของคุณเรียบง่ายด้วยการส่งข้อมูลที่มี จาก UI ไปยังเมธอด Callback ใช้ตรรกะทางธุรกิจภายใน เมธอด Callback ที่คุณเรียกใช้จากนิพจน์ Listener

การนําเข้า ตัวแปร และรวมถึง

ไลบรารีการเชื่อมโยงข้อมูลมีฟีเจอร์ต่างๆ เช่น การนำเข้า ตัวแปร และ ซึ่งรวมถึง การนำเข้าจะทำให้ดูชั้นเรียนอ้างอิงได้ง่ายภายในไฟล์เลย์เอาต์ของคุณ ตัวแปรช่วยให้คุณอธิบายพร็อพเพอร์ตี้ที่ใช้ในนิพจน์การเชื่อมโยงได้ รวมถึงช่วยให้คุณใช้เลย์เอาต์ที่ซับซ้อนในแอปของคุณได้

การนำเข้า

การนำเข้าช่วยให้คุณอ้างอิงคลาสภายในไฟล์เลย์เอาต์ได้ เช่น ในโค้ดที่มีการจัดการ คุณจะใช้องค์ประกอบ import ภายในองค์ประกอบ data จำนวน 0 รายการขึ้นไปได้ ตัวอย่างโค้ดต่อไปนี้นำเข้าคลาส 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>

คุณใช้ประเภทที่นำเข้าเพื่อแคสต์ส่วนของนิพจน์ได้ ดังต่อไปนี้ ตัวอย่าง แคสต์พร็อพเพอร์ตี้ 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.* โดยอัตโนมัติเช่นเดียวกับในโค้ดที่มีการจัดการ

ตัวแปร

คุณใช้องค์ประกอบ 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 ตัวแปรจะไม่ สังเกตการณ์แล้ว

เมื่อมีไฟล์เลย์เอาต์ที่แตกต่างกันสำหรับการกำหนดค่าต่างๆ (เช่น แนวนอนหรือแนวตั้ง) ระบบจะรวมตัวแปรเข้าด้วยกัน ต้องไม่มี คำจำกัดความของตัวแปรที่ขัดแย้งกันระหว่างไฟล์เลย์เอาต์เหล่านี้

คลาสการเชื่อมโยงที่สร้างขึ้นมีตัวตั้งค่าและ Getter สำหรับแต่ละรายการที่อธิบาย ตัวแปร ตัวแปรจะใช้ค่าโค้ดที่มีการจัดการเริ่มต้นจนกว่าตัวตั้งค่า เรียกว่า — null สำหรับประเภทการอ้างอิง, 0 สำหรับ int, false สำหรับ boolean ฯลฯ

ระบบสร้างตัวแปรพิเศษชื่อ context เพื่อใช้ในนิพจน์การเชื่อมโยง ตามความจำเป็น ค่าของ context คือค่า Context จากมุมมองราก 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>

แหล่งข้อมูลเพิ่มเติม

ดูข้อมูลเพิ่มเติมเกี่ยวกับการเชื่อมโยงข้อมูลได้ในแหล่งข้อมูลเพิ่มเติมต่อไปนี้

ตัวอย่าง

Codelab

บล็อกโพสต์