การเชื่อมโยงข้อมูล Android โดยใช้แท็กรวม


118

อัปเดตหมายเหตุ:

ตัวอย่างข้างต้นทำงานได้อย่างถูกต้องเนื่องจากรีลีส 1.0-rc4 แก้ไขปัญหาการต้องการตัวแปรที่ไม่จำเป็น

คำถามเดิม:

ฉันทำตามที่อธิบายไว้ในเอกสารและไม่ได้ผล:

main.xml:

<layout xmlns:andr...
    <data>
    </data>
       <include layout="@layout/buttons"></include>
....

buttons.xml:

<layout xmlns:andr...>
    <data>
    </data>
    <Button
        android:id="@+id/button"
        ...." />

MyActivity.java:

 ... binding = DataBindingUtil.inflate...
binding.button; ->cannot resolve symbol 'button'

วิธีรับปุ่ม?

คำตอบ:


207

ปัญหาคือเค้าโครงที่รวมไว้ไม่ได้ถูกมองว่าเป็นเค้าโครงที่เชื่อมโยงกับข้อมูล ในการทำให้เป็นหนึ่งคุณต้องส่งตัวแปร:

buttons.xml:

<layout xmlns:andr...>
  <data>
    <variable name="foo" type="int"/>
  </data>
  <Button
    android:id="@+id/button"
    ...." />

main.xml:

<layout xmlns:andr...
...
   <include layout="@layout/buttons"
            android:id="@+id/buttons"
            app:foo="@{1}"/>
....

จากนั้นคุณสามารถเข้าถึงปุ่มทางอ้อมผ่านช่องปุ่ม:

MainBinding binding = MainBinding.inflate(getLayoutInflater());
binding.buttons.button

ตั้งแต่ 1.0-rc4 (เพิ่งเปิดตัว) คุณไม่ต้องการตัวแปรอีกต่อไป คุณสามารถทำให้ง่ายขึ้นเพื่อ:

buttons.xml:

<layout xmlns:andr...>
  <Button
    android:id="@+id/button"
    ...." />

main.xml:

<layout xmlns:andr...
...
   <include layout="@layout/buttons"
            android:id="@+id/buttons"/>
....

6
1.0-rc4 แก้ไขปัญหาการต้องการตัวแปรที่ไม่จำเป็นแล้ว ตอนนี้คุณสามารถใช้เพียง: <include layout="@layout/buttons" android:id="@+id/buttons"/>. คุณยังคงต้องใช้รหัสเพื่อที่จะสร้างฟิลด์สาธารณะสำหรับคุณเพื่อให้คุณสามารถเข้าถึงมุมมองปุ่มได้
George Mount

1
มีใครมีปัญหาในการเชื่อมโยงเหตุการณ์การคลิกบนเค้าโครงหรือไม่?
Nilzor

5
Databinding พร้อมการสนับสนุนรวม developer.android.com/topic/libraries/data-binding/…
sowmia

1
จุดสำคัญที่ต้องจำนี่คือการได้รับการอ้างอิงปุ่มที่คุณต้องทำแทนbinding.{id of include tag}.button binding.buttonฉันใช้เวลาสักพักเพื่อคิดออก
Rishabh876

1
@NeonWarge มีตัวอย่างที่สมบูรณ์ที่เป็นdeveloper.android.com/topic/libraries/data-binding/... มันเพิ่ม "การผูกข้อมูลไม่รองรับการรวมเป็นลูกโดยตรงขององค์ประกอบการผสาน"
Ewan

38

ตัวอย่างที่สมบูรณ์อย่างง่าย

เพียงแค่ตั้งค่ารูปแบบรวมและการใช้งานidbinding.includedLayout.anyView

ตัวอย่างนี้ช่วยส่งค่าไปยัง<include& เข้าถึงมุมมองที่รวมอยู่ในโค้ด

ขั้นตอนที่ 1

คุณมีlayout_common.xmlต้องการส่งStringต่อไปยังเค้าโครงที่รวมไว้

คุณจะสร้างStringตัวแปรในรูปแบบและการอ้างนี้ไปStringTextView

<data>
    // declare fields
    <variable
        name="passedText"
        type="String"/>
</data>

<TextView
    android:id="@+id/textView"
    ...
    android:text="@{passedText}"/> //set field to your view.

ขั้นตอนที่ 2

รวมเค้าโครงนี้กับเค้าโครงหลัก ให้idเค้าโครงที่รวมไว้เพื่อให้เราสามารถใช้ในคลาสที่มีผลผูกพัน ตอนนี้คุณสามารถส่ง String passedTextไปยัง<includeแท็กของคุณ

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <LinearLayout
        ..
        >

        <include
            android:id="@+id/includedLayout"
            layout="@layout/layout_common"
            app:passedText="@{@string/app_name}" // here we pass any String 
            />

    </LinearLayout>
</layout>
  • คุณสามารถใช้ตอนนี้binding.includedLayout.textViewในชั้นเรียนของคุณได้
  • คุณสามารถส่งตัวแปรใด ๆ ไปยังเค้าโครงที่รวมไว้เช่นด้านบน

    ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
    binding.includedLayout.textView.setText("text");

หมายเหตุทั้งสองเค้าโครง (พาเรนต์และรวม) ควรถูกbinding layoutรวมไว้ด้วย<layout


ในคำตอบของคุณคุณจัดการเหตุการณ์ setText โดยทางโปรแกรมแทนที่จะเป็น TextView หากเป็นปุ่มแล้วคุณจะจัดการเหตุการณ์การคลิกอย่างไรฉันรู้ว่าโดยทางโปรแกรม binding.includedLayout.button.setOnClickListenerจะเป็นอีกทางเลือกหนึ่ง แต่ถ้าฉันต้องการใช้onClickแอตทริบิวต์ใน XML เอง?
iCantC

คุณสามารถส่งผ่านOnClickListenerไปยังเค้าโครงที่รวมไว้ได้ แม้กระทั่งคุณสามารถส่งผ่านอะไรก็ได้ในการผูกมัด ตรวจสอบคำตอบนี้หากคุณต้องการความช่วยเหลือเพิ่มเติมโปรดแจ้งให้เราทราบ stackoverflow.com/a/51722829/6891563
เขมราช

1
เมื่อฉันทำสิ่งนี้ฉันจะได้ช่องว่างสำหรับpassedText. ข้อแตกต่างเพียงอย่างเดียวคือฉันไม่รวมโค้ด MainActivity เพราะฉันแค่ต้องการส่งผ่านทรัพยากรสตริงใน <include> และปล่อยไว้อย่างนั้น ทำไมถึงว่างอยู่เสมอ?
Elliptica

3

สิ่งที่น่าสนใจอื่น ๆ ในเรื่องนี้คือคุณสามารถวางตัวแปรไปยังเค้าโครงที่นำเข้าจากเครื่องผูกดังนี้:

MainBinding binding = MainBinding.inflate(getLayoutInflater());
binding.buttons.setVariable(BR.varID, variable)

3

คุณสามารถทำให้การผูกของคุณทำงานกับการรวมของคุณได้เพียงแค่เพิ่ม ID ลงไปดังนี้:

<include
            android:id="@+id/loading"
            layout="@layout/loading_layout"
            bind:booleanVisibility="@{viewModel.showLoading}" />

2

เพียงตั้งรหัสสำหรับเค้าโครงรวมของคุณ

    <include
        android:id="@+id/layout"
        layout="@layout/buttons" />

แล้วก็

BUTTONSBINDING binding = yourMainBinding.layout;

BUTTONSBINDING คือ res / layout / buttons.xml

ตอนนี้:

binding.button.setText("simple_Way");
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.