4. Работа ViewGroup
Снова про root
класс для всех виджетов.
View
Android SDK включает множество виджетов, которые являются дочерним классом класса View
. Таким образом, каждый виджет является экземпляром класса View
, как и отражено на рисунке ниже.
Рис. 1. Иерархия класса View
. Источник изображения.
ViewGroup
Макет определяет структуру пользовательского интерфейса в вашем приложении, например в действии . Все элементы макета построены с использованием иерархии объектов View и ViewGroup . View
обычно рисует то, что пользователь может видеть и с чем может взаимодействовать. ViewGroup
— это невидимый контейнер, определяющий структуру макета для View
и других объектов ViewGroup
, как показано на рисунке 1.
Рисунок 1. Иллюстрация иерархии представлений, определяющей макет пользовательского интерфейса.
Объекты View
часто называются виджетами и могут быть одним из многих подклассов, таких как Button или TextView . Объекты ViewGroup
обычно называются макетами и могут относиться к одному из многих типов, предоставляющих другую структуру макета, например LinearLayout или ConstraintLayout
.
Объявить макет можно двумя способами:
Объявляйте элементы пользовательского интерфейса в XML. Android предоставляет простой словарь XML, соответствующий классам и подклассам
View
, например, для виджетов и макетов. Вы также можете использовать редактор макетов Android Studio для создания макета XML с помощью интерфейса перетаскивания.Создание экземпляров элементов макета во время выполнения. Ваше приложение может создавать объекты
View
иViewGroup
и программно управлять их свойствами.
Совет: Для отладки макета во время выполнения используйте инструмент «Инспектор макета» .
XML
Используя словарь XML Android, вы можете быстро разрабатывать макеты пользовательского интерфейса и элементы экрана, которые они содержат, точно так же, как вы создаете веб-страницы в HTML с рядом вложенных элементов.
Каждый файл макета должен содержать ровно один корневой элемент, который должен быть объектом View
или ViewGroup
. После определения корневого элемента вы можете добавить дополнительные объекты или виджеты макета в качестве дочерних элементов, чтобы постепенно построить иерархию View
, определяющую ваш макет. Например, вот макет XML, в котором используется вертикальный LinearLayout
для хранения TextView
и Button
:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout\_width="match\_parent"
android:layout\_height="match\_parent"
android:orientation="vertical" \>
<TextView android:id="@+id/text"
android:layout\_width="wrap\_content"
android:layout\_height="wrap\_content"
android:text="Hello, I am a TextView" />
<Button android:id="@+id/button"
android:layout\_width="wrap\_content"
android:layout\_height="wrap\_content"
android:text="Hello, I am a Button" />
</LinearLayout>
После объявления макета в XML сохраните файл с расширением .xml
в каталоге res/layout/
вашего проекта Android, чтобы он правильно скомпилировался.
Дополнительные сведения о синтаксисе XML-файла макета см. в разделе layout-resource .
Подключение XML-res
При компиляции приложения каждый файл макета XML компилируется в ресурс View
. Загрузите ресурс макета в реализацию обратного вызова Activity.onCreate() вашего приложения. Сделайте это, вызвав setContentView() , передав ему ссылку на ваш ресурс макета в форме: R.layout. _layout_file_name_
. Например, если ваш XML-макет сохранен как main_layout.xml
, загрузите его для своей Activity
следующим образом:
fun onCreate(savedInstanceState: Bundle) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_layout)
}
Платформа Android вызывает метод обратного вызова onCreate()
в вашем Activity
при запуске Activity
. Дополнительные сведения о жизненных циклах действий см. в разделе Введение в действия .
Атрибуты
Каждый объект View
и ViewGroup
поддерживает собственный набор атрибутов XML. Некоторые атрибуты специфичны для объекта View
. Например, TextView
поддерживает атрибут textSize
. Однако эти атрибуты также наследуются любыми объектами View
, расширяющими этот класс. Некоторые из них являются общими для всех объектов View
, поскольку они наследуются от корневого класса View
, например атрибут id
. Другие атрибуты считаются параметрами макета , которые являются атрибутами, описывающими определенные ориентации макета объекта View
, как определено родительским объектом ViewGroup
этого объекта.
ИДЕНТИФИКАТОР
Любой объект View
может иметь связанный с ним целочисленный идентификатор, позволяющий однозначно идентифицировать View
в дереве. При компиляции приложения этот идентификатор упоминается как целое число, но идентификатор обычно назначается в XML-файле макета в виде строки в атрибуте id
. Это атрибут XML, общий для всех объектов View
, и он определяется классом View
. Вы используете его очень часто. Синтаксис идентификатора внутри тега XML следующий:
android:id="@+id/my\_button"
Символ (@) в начале строки указывает, что синтаксический анализатор XML анализирует и расширяет остальную часть строки идентификатора и идентифицирует ее как ресурс идентификатора. Символ плюса (+
) означает, что это новое имя ресурса, которое необходимо создать и добавить к вашим ресурсам в файле R.java
.
Платформа Android предлагает множество других ресурсов для идентификации. При ссылке на идентификатор ресурса Android вам не нужен символ плюса , но вы должны добавить пространство имен пакета android
следующим образом:
android:id="@android:id/empty"
Пространство имен пакета android
указывает, что вы ссылаетесь на идентификатор из класса ресурсов android.R
, а не из класса локальных ресурсов.
Чтобы создавать View
и ссылаться на них из вашего приложения, вы можете использовать следующий общий шаблон:
Определите представление в файле макета и присвойте ему уникальный идентификатор, как в следующем примере:
<Button android:id="@+id/my\_button"
android:layout\_width="wrap\_content"
android:layout\_height="wrap\_content"
android:text="@string/my\_button\_text"/>
Создайте экземпляр объекта представления и запишите его из макета, обычно с помощью метода onCreate() , как показано в следующем примере:
val myButton: Button = findViewById(R.id.my_button)
Определение идентификаторов для объектов представления важно при создании RelativeLayout . В относительном макете родственные представления могут определять свой макет относительно другого родственного представления, на которое ссылается уникальный идентификатор.
Идентификатор не обязательно должен быть уникальным во всем дереве, но он должен быть уникальным в той части дерева, в которой вы ищете. Часто это может быть все дерево, поэтому лучше сделать его уникальным, если это возможно.
Параметры макета
Атрибуты макета XML с именем layout_ _something_
определяют параметры макета для View
, соответствующие ViewGroup
, в которой оно находится.
Каждый класс ViewGroup
реализует вложенный класс, расширяющий ViewGroup.LayoutParams . Этот подкласс содержит типы свойств, которые определяют размер и положение каждого дочернего View
в зависимости от ViewGroup
. Как показано на рисунке 2, родительская ViewGroup
й определяет параметры макета для каждого дочернего View
, включая дочернюю ViewGroup
.
Рисунок 2. Визуализация иерархии View
с параметрами макета, связанными с каждым View
.
Каждый подкласс LayoutParams
имеет свой собственный синтаксис для установки значений. Каждый дочерний элемент должен определять LayoutParams
, соответствующий его родительскому элементу, хотя он также может определять разные LayoutParams
для своих собственных дочерних элементов.
Вы можете указать ширину и высоту с точными измерениями, но, возможно, вам не захочется делать это часто. Чаще всего вы используете одну из этих констант для установки ширины или высоты:
wrap_content
: сообщает вашемуView
, что его размер соответствует размерам, требуемым его содержимым.match_parent
: сообщает вашемуView
, что оно должно стать настолько большим, насколько позволяет его родительскаяViewGroup
.
Как правило, мы не рекомендуем указывать ширину и высоту макета в абсолютных единицах, таких как пиксели. Лучшим подходом является использование относительных измерений, таких как независимые от плотности пиксельные единицы (dp), wrap_content
или match_parent
, поскольку это помогает вашему приложению правильно отображаться на экранах различных размеров. Принятые типы измерений определены в ресурсе макета .
Положение макета
View
имеет прямоугольную геометрию. Он имеет местоположение, выраженное как пара левой и верхней координат, и два измерения, выраженные как ширина и высота. Единицей местоположения и размеров является пиксель.
Вы можете получить местоположение представления, вызвав методы getLeft() и getTop() . Первый возвращает левую координату ( x ) прямоугольника, представляющего View
. Последний возвращает верхнюю координату ( y ) прямоугольника, представляющего View
. Эти методы возвращают расположение View
относительно его родителя. Например, когда getLeft()
возвращает 20, это означает, что представление расположено на 20 пикселей правее левого края его прямого родительского элемента.
Кроме того, существуют удобные методы, позволяющие избежать ненужных вычислений: а именно getRight() и getBottom(). Эти методы возвращают координаты правого и нижнего краев прямоугольника, представляющего View
. Например, вызов getRight()
аналогичен следующему вычислению: getLeft() + getWidth()
.