LayoutInflater
Однажды я пытался раскрыть вам тайное значение названия метода inflate() — слово inflate происходит от словосочетания in flat — в квартиру. Существует старинная традиция запускать в квартиру первым кота, который исследует все закоулки дома и заявляет о своём согласии жить в нём. Однако, мы сделаем вид, что поверили официальной версии, что по-английски inflate переводится как надувать, т.е. мы как бы надуваем данными из XML-файла объекты View.
Мы рассмотрим надувание компонентов применимо к LayoutInflater. Существует также класс MenuInflater, который использует тот же принцип.
Фрагменты тоже часто используют механизм надувания. Обратите внимание на сигнатуру метода onCreateView():
Сам механизм надувания прост и не требует особых объяснений, изучения достоин один аспект.
Вероятно, вам не раз приходилось писать/копировать такой код:
Даже у меня на сайте есть такие примеры. Недавно я заметил, что среда разработки ругается на последний параметр null.
Оказывается, это неправильно. Давайте изучать этот код.
Существует две версии метода inflate() для стандартных приложений.
В первом параметре указывается идентификатор ресурса разметки, который мы собираемся надуть. Во втором параметре указывается корневой компонент, к которому нужно присоединить надутые объекты. В третьем параметре (если он используется) указывается, нужно ли присоединять надутые объекты к корневому элементу.
LayoutInflater автоматически пытается присоединить надутые компоненты к корневому элементу. Иногда сама среда разработки может создать заготовку с использованием null, чтобы избежать возможного краха приложения. И разработчики используют предложенный вариант, хотя можно было использовать второй вариант метода с тремя параметрами.
Но давайте узнаем, чего мы лишаемся, когда используем null для корневого элемента.
Надувание компонентов часто применяется в адаптерах, когда разметка отдельного элемента списка задаётся в XML-файле, а затем динамически конвертируется в набор компонентов в методе getView():
Среда разработки заругалась. Исправим null на parent, который по названию вроде подходит под корневой элемент. Однако, запустив проект, мы получим ошибку. Йожкин кот, что мы наделали?!
Вспоминаем, что есть другая версия метода и исправляем на следующий вариант.
Пример работает, предупреждение не выводится. Но осадочек остался.
При использовании null среда разработки как-бы пытается сказать: «Я не знаю, какой элемент является родительским, поэтому прости, между нами всё кончено «, я буду использовать null.
Тогда зачем нам этот родительский элемент? На самом деле он может сыграть важную роль в различных ситуациях.
Проблемы могут возникнуть при использовании атрибутов android:layout_xxx в родительском элементе. В результате, не зная ничего о родителе, мы не можем использовать его LayoutParams и система будет игнорировать вашу разметку. А вы будете думать, что это баг.
Без LayoutParams родительский ViewGroup надует компоненты с настройками по умолчанию. И в большинстве случае это вполне работает.
Рассмотрим конкретный пример. Создадим разметку для отдельного элемента списка layout/list_item.xml.
Мы хотим использовать фиксированную высоту для каждого элемента и используем атрибут android:layout_height у родительского элемента.
Попробуем неправильный вариант.
В этом варианте игнорируется родитель и соответственно его настройки.
Результат на экране.
Теперь вам должна быть ясна разница между разными вариантами и правильный код для применения.
Но бывают случаи, когда использование null оправданно.
Одним из таких примеров является использование разметки в AlertDialog. Допустим, у нас есть код.
AlertDialog.Builder не нуждается в родительском элементе для построения диалогового окна.
Рассмотрим случаи, когда нужен true. Допустим, у нас есть отдельная разметка кнопки.
Мы можем программно присоединить кнопку к LinearLayout в активности или фрагменте.
Мы указали, что хотим надуть кнопку из его собственной разметки и присоединить полученную кнопку к LinearLayout (второй параметр). Это решение эквивалентно вызову метода с двумя параметрами.
Как вариант, можно не присоединять при надувании, а добавить программно через addView().
Другой случай использования true встречается при создании собственного компонента, когда применяется .
У файла разметки нет корневого ViewGroup и мы указываем свой собственный компонент на основе LinearLayout в качестве корневого. Если бы мы использовали в своей разметке вместо merge любой компонент, например, FrameLayout, то тогда был бы другой случай.
Теперь вы знаете, в каких ситуациях нужно использовать разные методы inflate(). Это как с котом — надутого кота можно обратить в null, когда вы не нуждаетесь в двойниках.
Источник
Полный список
— делаем свой вариант списка
На прошлом уроке мы узнали, зачем нужен класс LayoutInflater и сделали небольшой пример, на котором подробно рассмотрели метод inflate и его параметры. Для закрепления темы сделаем еще один, чуть более сложный пример.
Мы сделаем свой аналог списка. Для начала придумаем данные. Пусть это снова будет штатное расписание с именами работников, должностями и зарплатой. Т.е. каждый пункт нашего списка будет содержать три текстовых не редактируемых поля — name, position, salary. А пункты мы разместим в виде вертикального списка.
Для реализации нам понадобятся два layout-файла:
main.xml — основной экран для Activity, контейнер для пунктов списка
item.xml — экран с FrameLayout и тремя текстовыми полями в нем. Это будет пункт списка.
Приложение будет параллельно перебирать три массива данных, создавать для каждой тройки View-элемент из layout-файла item.xml, заполнять его данными и добавлять в вертикальный LinearLayout в main.xml.
Project name: P0411_LayoutInflaterList
Build Target: Android 2.3.3
Application name: LayoutInflaterList
Package name: ru.startandroid.develop.p0411layoutinflaterlist
Create Activity: MainActivity
ScrollView обеспечит нам прокрутку списка, если все пункты не влезут в экран. А в нем LinearLayout, в который мы будем добавлять элементы.
FrameLayout, и три TextView в нем.
Кодим реализацию. MainActivity.java:
Не так уж много нужно кода, чтобы сделать несложный список. Мы запускаем цикл по кол-ву элементов в массивах данных. В каждой итерации создаем View-элемент item из layout-файла item.xml. В нашем случае item — это FrameLayout, который содержит три TextView. Мы их находим в созданном item и заполняем данными из массивов.
В методе inflate мы указали root — linLayout, чтобы получить от него LayoutParams и далее использовать для настройки ширины. Также для наглядности раскрашиваем пункты методом setBackgroundColor.
Обратите внимание — третий параметр inflate мы указали false. Т.е. мы не стали сразу добавлять создаваемый View-элемент к linLayout, а делаем это в конце кода методом addView. Этому есть объяснение. Если бы мы указали true — то метод добавил бы item к linLayout и вернул бы нам linLayout, общий для всех пунктов списка. Через linLayout заполнять TextView необходимым нам текстом было бы затруднительно. Поэтому мы получаем пункт item (FrameLayout), заполняем его TextView данными и только потом помещаем к остальным пунктам в linLayout методом addView.
Все сохраним и запустим:
Список удался и работает прокрутка.
Урок получился короткий, но полезный. На всякий случай хочу заметить, что это еще не классический Android-список называемый List. Но этот пример значительно облегчит понимание списка. Т.к. принцип схож. Для построения List мы также должны будем предоставлять массив данных и layout-файл для пунктов. Этим и займемся на следующем уроке.
На следующем уроке:
— используем ListView для построения списка
Присоединяйтесь к нам в Telegram:
— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.
— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование
— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня
— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме
Источник
Русские Блоги
Введение в LayoutInflater (загрузчик макетов) в Android
Предисловие
Если читатели не читали эту серию блогов, рекомендуется сначала прочитать описание сообщения в блоге, чтобы у них было четкое понимание идеи последующего чтения блога.
Эта статья служит введением в серию LayoutInflater (загрузчик макетов) для Android. Содержание этой статьи относительно базовое. Рекомендуется сначала прочитать некоторые обзоры. Если вы чувствуете себя хорошо, вы можете пропустить эту главу и перейти непосредственно к статье об анализе исходного кода.
навигация
Обзор
(1) Общие сценарии использования LayoutInflater
(2) Введение в LayoutInflater
(3) Анализ связанных понятий во введении LayoutInflater
Общие сценарии использования LayoutInflater
Перед введением вернемся, где мы использовали LayoutInflater:
(1) В действии
(2) Во фрагменте
(3) В адаптере
(4) В некоторых особых случаях нужно использовать LayoutInflater, мы получаем это так
Вышеупомянутое использование является нашим обычным способом использования, и эти сцены имеют характерную особенность:Поскольку во всех этих сценариях необходимо преобразовать файл макета XML в представление, Так что если быть точнымОсновная функция LayoutInflater — загрузка макета.。
Фактически, LayoutInflater также имеет некоторые расширенные операции, которые могут быть реализованы нашим собственным способом, который будет представлен в собственно боевом разделе позже.
Напишите описание изображения здесь
Введение в LayoutInflater
Что касается вводного содержания LayoutInflater, блоггер считает, что любой контент, который ищут в Интернете, лучше, чем просмотр исходного кода. API более надежен, потому чтоAPI — это первое знакомство, И введение в исходный код Android относительно завершено.
LayoutInflater принадлежит к пакету android.view. В заголовке LayoutInflater есть введение о LayoutInflater:
Введение в исходный код LayoutInflater
Из-за недостатка места здесь перехвачена только часть изображений, вкратце:
(1) LayoutInflaterОсновная функция — создать экземпляр XML-файла в соответствующем объекте View.
(2) Как получить LayoutInflater в процессе разработки AndroidНе совсем новый, Являются LayoutInflater связанного контекста, полученным этими двумя методами:
(3) Если вы хотите использовать новый LayoutInflater для загрузки представления, вам необходимо использоватьcloneInContext(), А в новом LayoutInflater нужно вызватьsetFactory()НастроитьПосмотреть процессор
(4) Из соображений производительности XML-файлПредварительная обработкаЭто делается в процессе сборки.
(5) LayoutInflater не может загружать некомпилированные файлы XML, а LayoutInflater может загружаться только после анализа XmlPullParser.Ресурсы файла R。
LayoutInflater представляет соответствующее объяснение
После приведенного выше резюме у всех есть общее представление о LayoutInflater, так что все не слишком зациклены, позвольте мне объяснить один за другим.
(1) Основная функция LayoutInflater заключается в создании экземпляров XML-файлов в соответствующие объекты.
Фактически, когда вы используете LayoutInflater, вы также заметите, что это не что иное, как преобразование ресурсов макета в соответствующие представления с помощью LayoutInflater, а затем выполнение некоторых других операций, то естьРаспространенные сценарии LayoutInflaterНесколько ситуаций в:
(2) В процессе разработки Android LayoutInflater не был получен через новый?
В приведенном выше сценарии, помимо двух представленных методов Activity # getLayoutInflater () и getSystemService (), мы обнаружили, что также используются общие сценарии.
Фактически, метод LayoutInflater.from () является для нас официальным пакетом. Нижний уровень — это вызов метода getSystemService () для привязки LayoutInflater к объекту Context:
(3) Если вы хотите использовать новый LayoutInflater для загрузки, вам нужно использовать cloneInContext (), а в новом LayoutInflater вам нужно вызвать setFactory (), чтобы установить обработчик просмотра.
Обычно существует множество сценариев использования этого метода использования, например:
- Массовое получение настраиваемых атрибутов в XML
- Эффект динамического пилинга
- Динамически менять элементы в макете
Это достигается с помощью Factory в LayoutInflater, и эта часть введения будет представлена в самой боевой главе.
(4) Из соображений производительности предварительная обработка файла XML выполняется в процессе сборки.
Например, при записи ресурсов макета XML, если конечный символ опущен или какая-то странная операция, перед запуском программы на этапе сборки (этап сборки) появится сообщение об ошибке.
Здесь нарочно поставили терминатор, ошиблись
Здесь вы получите сообщение об ошибке, каждый XML будет иметь процесс предварительной компиляции, этот процесс происходит на этапе сборки (Build), а не во время выполнения.
Сообщение об ошибке XML
(5) LayoutInflater может загружать только файловые ресурсы R, проанализированные XmlPullParser.
Ресурсы файла R здесь относятся к этим файлам ресурсов
Роль LayoutInflater преобразует эти ресурсы в реальные объекты Android, и реализация этого процесса будет проанализирована в статье с исходным кодом.
Источник