Розташування View-елементів на екрані залежить від ViewGroup (Layout), в якій вони знаходяться.
LinearLayout – відображає View-елементи у вигляді одного рядка (якщо він Horizontal) або одного стовпця (якщо він Vertical).
TableLayout – відображає елементи у вигляді таблиці, в рядках і стовпцях.
RelativeLayout – для кожного елемента налаштовується його положення відносно інших елементів.
AbsoluteLayout – для кожного елемента вказується явна позиція на екрані в системі координат (x,y).
Розглянемо ці види детальніше:
Створимо проект для цього уроку. Назвемо його Layouts.
LinearLayout (LL)
Цей вид ViewGroup за замовчуванням пропонується при створенні нових layout-файлів. Він дійсно зручний і досить гнучкий, щоб створювати екрани різної складності. LL має властивість Orientation, яка визначає, як будуть розташовані дочірні елементи горизонтальною або вертикальною лінією.
Відкриємо layout-файл main.xml і поміщаємо до нього наступний код:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>
Тепер корінний елемент у нас LinearLayout з вертикальною орієнтацією.
Перетягніть зліва в корінний LinearLayout три кнопки. Вони вишикувалися вертикально.
Тепер у Properties міняємо для LL властивість Orientation на horizontal і зберігаємо його (CTRL+SHIFT+S) – кнопки вишикувалися горизонтально.
GroupView можна вкладати один в одну. Вкладемо в один LL два інших. Видаліть в main.xml всі елементи (три кнопки) крім корінного LL. Орієнтацію корінного LL вкажемо вертикальну і додамо до нього два нових горизонтальних LL. У списку елементів зліва вони знаходяться в розділі Layouts. Нагадую, що ви можете перетягувати елементи списку не лише на екран, але й на конкретний елемент на вкладці Outline.
У кожний горизонтальний LL додамо по три кнопки. Вийшло два горизонтальних рядка кнопок.
TableLayout (TL)
TL складається з рядків TableRow (TR). Кожна TR у свою чергу містить View-елементи, що формують стовпці. Тобто кількість View TR - це кількість стовпців. Але кількість стовпців у таблиці має бути рівним для всіх рядків. Тому, якщо в різних TR різна кількість View-елементів (стовпців), то загальна кількість визначається за TR з максимальною кількістю. Розглянемо на прикладі.
Створимо layout-файл tlayout.xml з корінним елементом TableLayout.
Додамо до корінного TableLayout три TableRow-рядка (з розділу Layouts зліва) і в кожний рядок додамо по дві кнопки. В результаті маємо таблицю 3*2.
Додамо до першого рядка ще пару кнопок. Тепер кількість стовпчиків - 4. Для другого та третього рядка третій та четвертий стовпчик нічим не заповнені.
В другий рядок додамо TextView и Button, і текст в TextView зробимо порожнім. В третьому рядку зробимо теж саме. Так як TextView порожній, то здається що стовпчик порожній.
Ширина стовпчика визначається його самим широким елементом. Додамо до TextView текст і бачимо, що стовпчик розширився.
TL може містити не лише TableRow, а й звичайні View.
RelativeLayout (RL)
В цьому виді Layout кожний View-елемент може бути розташований певним чином відносно іншого View-елемент.
Види відношень:
1) зліва, зправа, зверху, знизу зазначеного елемента (layout_toLeftOf, layout_toRightOf, layout_above, layout_below);
2) вирівнювання по лівому, правому, верхньому, нижньому краю зазначеного елемента (layout_alignLeft, layout_alignRight, layout_alignTop, layout_alignBottom);
3) вирівнювання по лівому, правому, верхньому, нижньому краю батьківського елементу (layout_alignParentLeft, layout_alignParentRight, layout_alignParentTop, layout_alignParentBottom);
4) вирівнювання по центру вертикально, по центру горизонтально, по центру вертикально і горизонтально щодо батьківського елементу (layout_centerVertical, layout_centerHorizontal, layout_centerInParent).
Створимо rlayout.xml та додамо наступний код:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Type here:">
</TextView>
<EditText
android:id="@+id/entry"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/label"
android:background="@android:drawable/editbox_background">
</EditText>
<Button
android:id="@+id/ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="@+id/entry"
android:layout_marginLeft="10dip"
android:text="OK">
</Button>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/ok"
android:layout_toLeftOf="@+id/ok"
android:text="Cancel">
</Button>
</RelativeLayout>
Тут у нас корінний елемент RelativeLayout. Отримали такий екран:
Нам цікавий xml-код. Відразу коротко опишемо незнайомі атрибути та їх значення:
- слово android в назві кожного атрибута – це namespace.
- id – це ID елементу.
- layout_width (ширина елементу) та layout_height (висота елементу) можуть задаватись в абсолютних значеннях, а можуть бути наступними: fill_parent (максимально можлива ширина або висота в межах батьківського елементу) та wrap_content (ширина або висота визначається по вмісту елемента). В хелпі вказано, що є ще match_parent. Це теж саме, що і fill_parent. По якимсь причинам, розробники системи вирішили, що назва match_parent зручніша, і від fill_parent поступово будуть відмовлятись. А поки його залишили для сумісності. Так що запам'ятайте, що match_parent = fill_parent і надалі будемо намагатись використовувати match_parent.
Зараз повернемося до наших елементів. В прикладі ми бачимо TextView, EditText і два Button – OK та Cancel. Давайте детальніше розберемо атрибути.
TextView
android:id="@+id/label" - ID;
android:layout_width="match_parent" - займає всю доступну йому ширину (хоча це і не видно на екрані);
android:layout_height="wrap_content" - висота по вмісту.
EditText
android:id="@+id/entry" - ID;
android:layout_width="match_parent" - вся доступна йому ширина;
android:layout_height="wrap_content" - висота по вмісту;
android:layout_below="@id/label" - розташований нижче TextView (посилання по ID).
Button_OK
android:id="@+id/ok" – ID;
android:layout_width="wrap_content" - ширина по вмісту;
android:layout_height="wrap_content" – висота по вмісту;
android:layout_below="@id/entry" - розташований нижче EditText;
android:layout_alignParentRight="true" - вирівняний по правому краю батьківського елементу;
android:layout_marginLeft="10dip" – має відступ зліва (щоб Button_Cancel не щільно прилягав).
Button_Cancel
android:layout_width="wrap_content" - ширина по вмісту;
android:layout_height="wrap_content" – висота по вмісту;
android:layout_toLeftOf="@id/ok" - розташований зліва від Button_OK;
android:layout_alignTop="@id/ok" - вирівняний по верхньому краю Button_OK.
Зверніть увагу, що у View-елемента може не бути ID (android:id). Наприклад, для TextView він зазвичай не потрібен, оскільки вони найчастіше статичні і ми до них майже не звертаємося при роботі програми. Інша справа EditText – ми працюємо з вмістом текстового поля, та Button – нам треба обробляти натискання і відповідно знати, яка саме кнопка натиснута.
AbsoluteLayout (AL)
Забезпечує абсолютне позиціювання елементів на екрані. Ви вказуєте координати для верхнього лівого кута компоненту.
Створимо alayout.xml з корінним AbsoluteLayout.
Тепер спробуйте перетягуванням пододавати різні елементи на екран. Вони не вишиковуються, як при LinearLayout або TableLayout, а стають там, куди ви їх перетягнули. Тобто це абсолютне позиціювання.
Відкриваємо xml-код і бачимо, що для задання координат використовуються layout_x та layout_y.
<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="42dp"
android:layout_y="62dp"
android:text="Button">
</Button>
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="142dp"
android:layout_y="131dp"
android:text="TextView">
</TextView>
<CheckBox
android:id="@+id/checkBox1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="55dp"
android:layout_y="212dp"
android:text="CheckBox">
</CheckBox>
<RadioButton
android:id="@+id/radioButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="171dp"
android:layout_y="318dp"
android:text="RadioButton">
</RadioButton>
</AbsoluteLayout>
Спочатку здається, що це найбільш зручний і інтуїтивно зрозумілий спосіб розташування елементів на екрані - вони відразу розташовуються там, де треба. Але це тільки у випадку, коли ви програмуєте для екрану з конкретною роздільною здатністю. Якщо відкрити таку програму на іншому екрані, всі елементи змістяться і вийде не так, як ви планували. Тому цей Layout не рекомендується використовувати. І його сумісність з майбутніми версіями Android не гарантується.