Созданные классы привязки

Библиотека привязки данных генерирует классы привязки, которые можно использовать для доступа к переменным и представлениям макета. В этой документации показано, как создавать и настраивать сгенерированные классы привязки.

Созданный класс привязки связывает переменные макета с представлениями внутри макета. Вы можете настроить название и комплектацию привязки. Все созданные классы привязки наследуются от класса ViewDataBinding .

Класс привязки создается для каждого файла макета. По умолчанию имя класса — это имя файла макета, преобразованное в регистр Pascal, с добавленным к нему суффиксом Binding . Так, например, если имя файла макета — activity_main.xml , соответствующий сгенерированный класс — ActivityMainBinding . Этот класс содержит все привязки свойств макета к представлениям макета и знает, как присваивать значения выражениям привязки.

Создать объект привязки

Объект привязки создается сразу после раздувания макета, чтобы гарантировать, что иерархия представлений не будет изменена до привязки к представлениям с выражениями в макете. Самый распространенный метод привязки объекта к макету — использование статических методов класса привязки. Вы можете расширить иерархию представления и привязать к ней объект, используя метод inflate() класса привязки, как показано в следующем примере:

Котлин

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    val binding: MyLayoutBinding = MyLayoutBinding.inflate(layoutInflater)

    setContentView(binding.root)
}

Ява

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater());

    setContentView(binding.root);
}

Существует альтернативная версия метода inflate() , которая принимает объект ViewGroup в дополнение к объекту LayoutInflater , как показано в следующем примере:

Котлин

val binding: MyLayoutBinding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false)

Ява

MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false);

Если макет надувается с помощью другого механизма, его можно привязать отдельно, следующим образом:

Котлин

val binding: MyLayoutBinding = MyLayoutBinding.bind(viewRoot)

Ява

MyLayoutBinding binding = MyLayoutBinding.bind(viewRoot);

Иногда вы не знаете заранее тип привязки. В таких случаях вы можете создать привязку с помощью класса DataBindingUtil , как показано в следующем фрагменте кода:

Котлин

val viewRoot = LayoutInflater.from(this).inflate(layoutId, parent, attachToParent)
val binding: ViewDataBinding? = DataBindingUtil.bind(viewRoot)

Ява

View viewRoot = LayoutInflater.from(this).inflate(layoutId, parent, attachToParent);
ViewDataBinding binding = DataBindingUtil.bind(viewRoot);

Если вы используете элементы привязки данных внутри адаптера Fragment , ListView или RecyclerView , вы можете предпочесть использовать методы inflate() классов привязок или класса DataBindingUtil , как показано в следующем примере кода:

Котлин

val listItemBinding = ListItemBinding.inflate(layoutInflater, viewGroup, false)
// or
val listItemBinding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false)

Ява

ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false);
// or
ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);

Просмотры с идентификаторами

Библиотека привязки данных создает неизменяемое поле в классе привязки для каждого представления, имеющего идентификатор в макете. Например, библиотека привязки данных создает поля firstName и lastName типа TextView из следующего макета:

<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}"
   android:id="@+id/firstName"/>
       <TextView android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@{user.lastName}"
  android:id="@+id/lastName"/>
   </LinearLayout>
</layout>

Библиотека извлекает представления, включая идентификаторы, из иерархии представлений за один проход. Этот механизм может быть быстрее, чем вызов метода findViewById() для каждого представления в макете.

Идентификаторы не так необходимы, как без привязки данных, но все же есть случаи, когда доступ к представлениям необходим из кода.

Переменные

Библиотека привязки данных генерирует методы доступа для каждой переменной, объявленной в макете. Например, следующий макет генерирует методы установки и получения в классе привязки для переменных 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>

Просмотрзаглушек

В отличие от обычных представлений, объекты ViewStub начинаются как невидимые представления. Когда они становятся видимыми или явно раздуваются, они заменяют себя в макете, раздувая другой макет.

Поскольку ViewStub исчезает из иерархии представлений, представление в объекте привязки также должно исчезнуть, чтобы его можно было затребовать при сборке мусора. Поскольку представления являются окончательными, объект ViewStubProxy занимает место ViewStub в созданном классе привязки, предоставляя вам доступ к ViewStub , если он существует, и доступ к расширенной иерархии представлений, когда ViewStub расширяется.

При раздувании другого макета для нового макета должна быть установлена ​​привязка. Таким образом, ViewStubProxy должен прослушивать ViewStub OnInflateListener и при необходимости устанавливать привязку. Поскольку одновременно может существовать только один прослушиватель, ViewStubProxy позволяет установить OnInflateListener , который вызывается после установления привязки.

Немедленное связывание

Когда изменяется переменная или наблюдаемый объект, привязка должна измениться перед следующим кадром. Однако бывают случаи, когда привязку необходимо выполнить немедленно. Для принудительного выполнения используйте метод executePendingBindings() .

Динамические переменные

Иногда конкретный класс привязки неизвестен. Например, RecyclerView.Adapter , работающий с произвольными макетами, не знает конкретного класса привязки. Он должен присвоить значение привязки во время вызова метода onBindViewHolder() .

В следующем примере все макеты, к которым привязывается RecyclerView , имеют переменную item . Объект BindingHolder имеет метод getBinding() , возвращающий базовый класс ViewDataBinding .

Котлин

override fun onBindViewHolder(holder: BindingHolder, position: Int) {
    item: T = items.get(position)
    holder.binding.setVariable(BR.item, item);
    holder.binding.executePendingBindings();
}

Ява

public void onBindViewHolder(BindingHolder holder, int position) {
    final T item = items.get(position);
    holder.getBinding().setVariable(BR.item, item);
    holder.getBinding().executePendingBindings();
}

Фоновый поток

Вы можете изменить свою модель данных в фоновом потоке, если это не коллекция. Привязка данных локализует каждую переменную или поле во время оценки, чтобы избежать проблем с параллелизмом.

Имена пользовательских классов привязки

По умолчанию класс привязки создается на основе имени файла макета, начинающегося с заглавной буквы, без подчеркивания ( _ ), следующей буквы с заглавной буквы и суффикса слова Binding . Например, файл макета contact_item.xml создает класс ContactItemBinding . Класс помещается в пакет databinding в пакете модуля. Например, если пакет модуля — com.example.my.app , то класс привязки помещается в пакет com.example.my.app.databinding .

Классы привязки можно переименовать или поместить в разные пакеты, изменив атрибут class элемента data . Например, следующий макет создает класс привязки ContactItem в пакете databinding в текущем модуле:

<data class="ContactItem">
    ...
</data>

Вы можете создать класс привязки в другом пакете, добавив к имени класса точку. В следующем примере создается класс привязки в пакете модуля:

<data class=".ContactItem">
    ...
</data>

Вы также можете использовать полное имя пакета, в котором хотите создать класс привязки. В следующем примере создается класс привязки ContactItem в пакете com.example :

<data class="com.example.ContactItem">
    ...
</data>

Дополнительные ресурсы

Дополнительные сведения о привязке данных см. в следующих дополнительных ресурсах.

{% дословно %} {% дословно %} {% дословно %} {% дословно %}