Привязка данных Android с использованием тега include
Обновление заметки:
Приведенный выше пример работает правильно, потому что в выпуске 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'
как получить кнопку?
Ответы
Ответ 1
Проблема в том, что включенный макет не рассматривается как макет с привязкой к данным. Чтобы заставить его действовать как единое целое, вам нужно передать переменную:
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"/>
....
Ответ 2
Легко завершенный пример
Просто установите id
для включенного макета и используйте binding.includedLayout.anyView
.
Этот пример помогает передать значение <include
и получить доступ к включенным представлениям в коде.
Шаг 1
У вас есть layout_common.xml
, вы хотите передать String
во включенный макет.
Вы создадите String
переменную в макете и передадите эту String
в TextView
.
<data>
// declare fields
<variable
name="passedText"
type="String"/>
</data>
<TextView
android:id="@+id/textView"
...
android:text="@{passedText}"/> //set field to your view.
Шаг 2
Включить этот макет в родительский макет. Присвойте id
включенному макету, чтобы мы могли использовать его в классе привязки. Теперь вы можете передать 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 = ActivityMainBinding.inflate(getLayoutInflater()); binding.includedLayout.textView.setText("text");
Note-, что оба макета (родительский и включенный) должны быть binding layout
, завернутым в <layout
Ответ 3
Еще одна интересная вещь в том, что вы можете использовать переменные pas для импортированного макета из этого связующего:
MainBinding binding = MainBinding.inflate(getLayoutInflater());
binding.buttons.setVariable(BR.varID, variable)