Просмотр привязки . Часть Android Jetpack .

Привязка представления — это функция, которая упрощает написание кода, взаимодействующего с представлениями. Как только привязка представления включена в модуле, он генерирует класс привязки для каждого файла макета XML, присутствующего в этом модуле. Экземпляр класса привязки содержит прямые ссылки на все представления, имеющие идентификатор в соответствующем макете.

В большинстве случаев привязка представления заменяет findViewById .

Настраивать

Привязка представления включается для каждого модуля отдельно. Чтобы включить привязку представления в модуле, установите для параметра сборки viewBinding значение true в файле build.gradle уровня модуля, как показано в следующем примере:

классный

android {     ...     buildFeatures {         viewBinding true     } }

Котлин

android {     ...     buildFeatures {         viewBinding = true     } }

Если вы хотите, чтобы файл макета игнорировался при создании классов привязки, добавьте атрибут tools:viewBindingIgnore="true" в корневое представление этого файла макета:

<LinearLayout         ...         tools:viewBindingIgnore="true" >     ... </LinearLayout> 

Использование

Если привязка представления включена для модуля, класс привязки создается для каждого файла макета XML, содержащегося в модуле. Каждый класс привязки содержит ссылки на корневое представление и все представления, имеющие идентификатор. Имя класса привязки генерируется путем преобразования имени XML-файла в регистр Паскаля и добавления в конец слова «Привязка».

Например, рассмотрим файл макета с именем result_profile.xml , который содержит следующее:

<LinearLayout ... >     <TextView android:id="@+id/name" />     <ImageView android:cropToPadding="true" />     <Button android:id="@+id/button"         android:background="@drawable/rounded_button" /> </LinearLayout> 

Созданный класс привязки называется ResultProfileBinding . Этот класс имеет два поля: TextView с именем name и Button с именем button . ImageView в макете не имеет идентификатора, поэтому в классе привязки на него нет ссылки.

Каждый класс привязки также включает метод getRoot() , предоставляющий прямую ссылку на корневое представление соответствующего файла макета. В этом примере метод getRoot() в классе ResultProfileBinding возвращает корневое представление LinearLayout .

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

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

Чтобы настроить экземпляр класса привязки для использования с действием, выполните следующие шаги в методе onCreate() действия:

  1. Вызовите статический метод inflate() включенный в сгенерированный класс привязки. При этом создается экземпляр класса привязки, который будет использоваться действием.
  2. Получите ссылку на корневое представление, вызвав метод getRoot() или используя синтаксис свойств Kotlin .
  3. Передайте корневое представление в setContentView() чтобы сделать его активным представлением на экране.

Эти шаги показаны в следующем примере:

Котлин

private lateinit var binding: ResultProfileBinding  override fun onCreate(savedInstanceState: Bundle?) {     super.onCreate(savedInstanceState)     binding = ResultProfileBinding.inflate(layoutInflater)     val view = binding.root     setContentView(view) }

Ява

private ResultProfileBinding binding;  @Override protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     binding = ResultProfileBinding.inflate(getLayoutInflater());     View view = binding.getRoot();     setContentView(view); }

Теперь вы можете использовать экземпляр класса привязки для ссылки на любое представление:

Котлин

binding.name.text = viewModel.name binding.button.setOnClickListener { viewModel.userClicked() }

Ява

binding.name.setText(viewModel.getName()); binding.button.setOnClickListener(new View.OnClickListener() {     viewModel.userClicked() });

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

Чтобы настроить экземпляр класса привязки для использования с фрагментом, выполните следующие шаги в методе onCreateView() фрагмента:

  1. Вызовите статический метод inflate() включенный в сгенерированный класс привязки. При этом создается экземпляр класса привязки для использования фрагментом.
  2. Получите ссылку на корневое представление, вызвав метод getRoot() или используя синтаксис свойств Kotlin .
  3. Верните корневое представление из метода onCreateView() чтобы сделать его активным представлением на экране.

Котлин

private var _binding: ResultProfileBinding? = null // This property is only valid between onCreateView and // onDestroyView. private val binding get() = _binding!!  override fun onCreateView(     inflater: LayoutInflater,     container: ViewGroup?,     savedInstanceState: Bundle? ): View? {     _binding = ResultProfileBinding.inflate(inflater, container, false)     val view = binding.root     return view }  override fun onDestroyView() {     super.onDestroyView()     _binding = null }

Ява

private ResultProfileBinding binding;  @Override public View onCreateView (LayoutInflater inflater,                           ViewGroup container,                           Bundle savedInstanceState) {     binding = ResultProfileBinding.inflate(inflater, container, false);     View view = binding.getRoot();     return view; }  @Override public void onDestroyView() {     super.onDestroyView();     binding = null; }

Теперь вы можете использовать экземпляр класса привязки для ссылки на любое представление:

Котлин

binding.name.text = viewModel.name binding.button.setOnClickListener { viewModel.userClicked() }

Ява

binding.name.setText(viewModel.getName()); binding.button.setOnClickListener(new View.OnClickListener() {     viewModel.userClicked() });

Предоставление подсказок для различных конфигураций

Когда вы объявляете представления в нескольких конфигурациях, иногда имеет смысл использовать другой тип представления в зависимости от конкретного макета. Следующий фрагмент кода показывает пример этого:

# in res/layout/example.xml  <TextView android:id="@+id/user_bio" />  # in res/layout-land/example.xml  <EditText android:id="@+id/user_bio" /> 

В этом случае вы можете ожидать, что сгенерированный класс предоставит поле userBio типа TextView , поскольку TextView является общим базовым классом. Из-за технических ограничений генератор кода привязки представления не может это определить и вместо этого генерирует поле View . Для этого потребуется привести поле позже с binding.userBio as TextView .

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

# in res/layout/example.xml (unchanged)  <TextView android:id="@+id/user_bio" />  # in res/layout-land/example.xml  <EditText android:id="@+id/user_bio" tools:viewBindingType="TextView" /> 

В другом примере предположим, что у вас есть два макета: один содержит BottomNavigationView , а другой — NavigationRailView . Оба класса расширяют NavigationBarView , который содержит большую часть деталей реализации. Если вашему коду не нужно точно знать, какой подкласс присутствует в текущем макете, вы можете использовать tools:viewBindingType , чтобы установить сгенерированный тип NavigationBarView в обоих макетах:

# in res/layout/navigation_example.xml  <BottomNavigationView android:id="@+id/navigation" tools:viewBindingType="NavigationBarView" />  # in res/layout-w720/navigation_example.xml  <NavigationRailView android:id="@+id/navigation" tools:viewBindingType="NavigationBarView" /> 

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

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

      <TextView tools:viewBindingType="ImageView" /> <!-- ImageView is not related to TextView. -->   <TextView tools:viewBindingType="Button" /> <!-- Button is not a superclass of TextView. --> 
  • Последний тип должен разрешаться последовательно во всех конфигурациях.

Отличия от findViewById

Привязка представления имеет важные преимущества перед использованием findViewById :

  • Нулевая безопасность: поскольку привязка представления создает прямые ссылки на представления, риск возникновения исключения нулевого указателя из-за недопустимого идентификатора представления отсутствует. Кроме того, если представление присутствует только в некоторых конфигурациях макета, поле, содержащее его ссылку в классе привязки, помечается @Nullable .
  • Безопасность типов: поля в каждом классе привязки имеют типы, соответствующие представлениям, на которые они ссылаются в XML-файле. Это означает, что нет риска исключения приведения класса.

Эти различия означают, что несовместимость между вашим макетом и кодом приводит к сбою сборки во время компиляции, а не во время выполнения.

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

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

  • Ускоренная компиляция: привязка представления не требует обработки аннотаций, поэтому время компиляции сокращается.
  • Простота использования: привязка представления не требует наличия XML-файлов макета со специальными тегами, поэтому его можно быстрее внедрить в свои приложения. Как только вы включаете привязку представления в модуле, она автоматически применяется ко всем макетам этого модуля.

С другой стороны, привязка представления имеет следующие ограничения по сравнению с привязкой данных:

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

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

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

Блоги

Видео

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