Liên kết dữ liệu Android sử dụng thẻ bao gồm


116

Cập nhật ghi chú:

Ví dụ trên hoạt động đúng cách , vì bản phát hành 1.0-rc4 đã khắc phục sự cố cần biến không cần thiết.

Câu hỏi ban đầu:

Tôi làm chính xác như nó được mô tả trong tài liệu và nó không hoạt động:

main.xml:

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

button.xml:

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

MyActivity.java:

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

làm thế nào để có được nút?

Câu trả lời:


206

Vấn đề là bố cục bao gồm không được coi là bố cục ràng buộc dữ liệu. Để làm cho nó hoạt động như một, bạn cần truyền một biến:

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

Sau đó, bạn có thể truy cập các nút một cách gián tiếp thông qua trường nút:

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

Kể từ phiên bản 1.0-rc4 (vừa được phát hành), bạn không cần biến nữa. Bạn có thể đơn giản hóa nó thành:

button.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 hiện đã khắc phục sự cố cần biến không cần thiết. Bây giờ bạn có thể sử dụng đơn giản: <include layout="@layout/buttons" android:id="@+id/buttons"/>. Bạn vẫn cần id để nó tạo ra trường công khai cho bạn để bạn có thể truy cập Dạng xem nút.
George Mount

1
Có ai khác đang gặp vấn đề khi liên kết các sự kiện nhấp chuột trên bố cục không?
Nilzor

5
Databinding với hỗ trợ bao gồm. developer.android.com/topic/libraries/data-binding/…
gieomia

1
Điểm chính cần nhớ ở đây là để lấy tham chiếu nút, bạn cần làm binding.{id of include tag}.buttonthay vì binding.button. Tôi đã mất một thời gian để tìm ra nó.
Rishabh876

1
@NeonWarge Có một ví dụ đầy đủ tại developer.android.com/topic/libraries/data-binding/… . Nó cho biết thêm "Liên kết dữ liệu không hỗ trợ bao gồm dưới dạng con trực tiếp của một phần tử hợp nhất"
Ewan

38

Ví dụ hoàn chỉnh dễ dàng

Chỉ cần đặt thành idbố cục bao gồm và sử dụng binding.includedLayout.anyView.

Ví dụ này giúp chuyển một giá trị đến <include& truy cập các chế độ xem được bao gồm trong mã.

Bước 1

Bạn có layout_common.xml, muốn chuyển Stringđến bố cục bao gồm.

Bạn sẽ tạo Stringbiến trong bố cục và tham chiếu Stringđến TextView.

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

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

Bước 2

Bao gồm bố cục này vào bố cục mẹ. Đưa ra một idbố cục được bao gồm để chúng ta có thể sử dụng bố cục đó trong lớp ràng buộc. Bây giờ bạn có thể chuyển Chuỗi passedTextvào <includethẻ của mình .

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>
  • Bạn có thể sử dụng ngay bây giờ binding.includedLayout.textViewtrong lớp học của mình.
  • Bạn có thể chuyển bất kỳ biến nào vào bố cục bao gồm như trên.

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

Lưu ý Cả hai bố cục (chính và bao gồm) phải được binding layoutbao bọc bằng<layout


Trong câu trả lời của mình, bạn đã xử lý sự kiện setText theo chương trình, Thay vì TextView nếu nó là Nút, thì bạn sẽ xử lý sự kiện nhấp chuột của nó như thế nào. Tôi biết rằng theo chương trình binding.includedLayout.button.setOnClickListenersẽ là lựa chọn thay thế, nhưng nếu tôi muốn sử dụng onClickthuộc tính trong XML thì sao chinh no ?
iCantC

Bạn có thể chuyển OnClickListenersang bố cục bao gồm. thậm chí bạn có thể vượt qua bất cứ điều gì ràng buộc. Kiểm tra câu trả lời này, nếu bạn cần thêm trợ giúp, hãy cho tôi biết. stackoverflow.com/a/51722829/6891563
Khemraj

1
Khi tôi làm điều này, tôi chỉ nhận được một trường trống cho passedText. Sự khác biệt duy nhất là tôi không bao gồm mã MainActivity bởi vì tôi chỉ muốn chuyển tài nguyên chuỗi trong <include> và để nó như vậy. Tại sao nó luôn trống?
Elliptica

3

Một điều thú vị khác về điều này là bạn có thể dán các biến vào bố cục đã nhập từ trình kết dính như thế này:

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

3

Bạn có thể làm cho ràng buộc của mình hoạt động trên đó, chỉ cần thêm ID vào nó như sau:

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

2

chỉ cần đặt một id cho bố cục bao gồm của bạn

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

sau đó

BUTTONSBINDING binding = yourMainBinding.layout;

BUTTONSBINDING là res / layout / button.xml

hiện nay :

binding.button.setText("simple_Way");
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.