Визначення інтерфейсу у файлі XML. Файли Layout
Як правило, для визначення візуального інтерфейсу в проєктах під Android використовуються спеціальні файли XML. Ці файли є ресурсами розмітки та містять визначення візуального інтерфейсу у вигляді коду XML. Такий підхід нагадує створення веб-сайтів, де інтерфейс визначається у файлах HTML, а логіка додатку — в коді JavaScript.
Оголошення користувацького інтерфейсу в XML дозволяє відокремити інтерфейс додатку від коду. Це означає, що ми можемо змінювати визначення інтерфейсу без зміни Java-коду. Наприклад, можна створити XML-розмітки для різних орієнтацій екрана, розмірів пристроїв, мов тощо.
Файли розмітки графічного інтерфейсу розташовуються в проєкті в каталозі res/layout. За замовчуванням при створенні проєкту з порожньою activity вже є один файл ресурсів розмітки activity_main.xml, який може виглядати приблизно так:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
У файлі визначаються всі графічні елементи та їхні атрибути, які складають інтерфейс. При створенні розмітки в XML слід дотримуватися деяких правил: кожен файл розмітки повинен містити один кореневий елемент, який повинен представляти об'єкт View або ViewGroup.
У цьому випадку кореневим елементом є елемент ConstraintLayout, який містить елемент TextView.
Як правило, кореневий елемент містить визначення використовуваних просторів імен XML. Наприклад, у коді за замовчуванням у ConstraintLayout ми можемо побачити такі атрибути:
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
Кожен простір імен задається таким чином: xmlns:префікс="назва_ресурсу". Наприклад, у
xmlns:android="http://schemas.android.com/apk/res/android"
Назва ресурсу (або URI - Uniform Resource Indentifier) - "http://schemas.android.com/apk/res/android". І цей ресурс зіставляється з префіксом android (xmlns:android). Тобто через префікс ми зможемо посилатися на функціональність цього простору імен.
Кожен простір імен визначає деяку функціональність, яка використовується в застосунку, наприклад, надають теги та атрибути, які необхідні для побудови застосунку.
xmlns:android="http://schemas.android.com/apk/res/android": містить основні атрибути, які надаються платформою Android, застосовуються в елементах керування та визначають їхні візуальні властивості (наприклад, розмір, позиціонування). Наприклад, у кодіConstraintLayoutвикористовується такий атрибут із простору імен"http://schemas.android.com/apk/res/android":
android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto": містить атрибути, що визначені в межах програми. Наприклад, у кодіTextView:
app:layout_constraintBottom_toBottomOf="parent"
xmlns:tools="http://schemas.android.com/tools": застосовується для роботи з режимі дизайнера в Android Studio
Це найпоширеніші простори імен. І зазвичай кожен кореневий елемент (не обов'язково тільки ConstraintLayout) їх містить. Однак, якщо ви не плануєте користуватися графічним дизайнером в Android Studio і хочете працювати цілком у коді xml, то відповідно сенсу в просторі імен "http://schemas.android.com/tools" немає, і його можна прибрати.
Під час компіляції кожен XML-файл розмітки компілюється в ресурс View. Завантаження ресурсу розмітки здійснюється в методі Activity.onCreate. Щоб встановити розмітку для поточного об'єкта activity, треба в метод setContentView() як параметр передати посилання на ресурс розмітки.
setContentView(R.layout.activity_main);
Для отримання посилання на ресурс у коді java необхідно використовувати вираз R.layout.[назва_ресурсу]. Назва ресурсу layout збігатиметься з ім'ям файлу, тому щоб використовувати файл activity_main.xml як джерело візуального інтерфейсу, можна визначити наступний код у класі MainActivity:
package com.example.viewapp;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// загрузка интерфейса из файла activity_main.xml
setContentView(R.layout.activity_main);
}
}
Додавання файлу layout
Але у нас може бути і кілька різних ресурсів layout. Як правило, кожен окремий клас Activity використовує свій файл layout. Або для одного класу Activity може використовуватися відразу кілька різних файлів layout.
Наприклад, додамо в проєкт новий файл розмітки інтерфейсу. Для цього натиснемо на папку res/layout правою кнопкою миші і в меню, що з'явилося, виберемо пункт New -> Layout Resource File:

Після цього в спеціальному віконці буде запропоновано вказати ім'я і кореневий елемент для файлу layout:

Як назву вкажемо second_layout. Усі інші налаштування залишимо за замовчуванням:
- у полі
Root elementвказується кореневий елемент. За замовчуванням цеandroidx.constraintlayout.widget.ConstraintLayout. - поле
Sourceset вказує, куди поміщати новий файл. За замовчуванням цеmain- область проєкту, з якою ми власне працюємо під час розроблення програми. - поле
Directory mainвказує папку в рамках каталогу, обраного в попередній опції, в який власне поміщається новий файл. За замовчуванням для файлів із розміткою інтерфейсу цеlayout.
Після цього в папку res/layout буде додано новий файл second_layout.xml, з яким ми можемо працювати так само, як і з activity_main.xml. Зокрема, відкриємо файл second_layout.xml і змінимо його вміст таким чином:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/header"
android:text="Welcome to Android"
android:textSize="26sp"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Тут визначено текстове поле TextView, яке має такі атрибути:
android:id- ідентифікатор елемента, через який ми зможемо посилатися на нього в коді. У записіandroid:id="@+id/header"символ@вказує XML-парсеру використовувати решту рядка атрибута як ідентифікатор. А знак+означає, що якщо для елемента не визначеноidзі значеннямheader, то його слід визначити.android:text- текст елемента - на екран виводитиметься рядок"Welcome to Android".android:textSize- висота шрифту (тут26одиниць)android:layout_width- ширина елемента. Значення"match_parent"вказує, що елемент буде розтягуватися по всій ширині контейнераConstraintLayoutandroid:layout_height- висота елемента. Значення"match_parent"вказує, що елемент буде розтягуватися по всій висоті контейнераConstraintLayout
Застосуємо цей файл як визначення графічного інтерфейсу в класі MainActivity:
package com.example.viewapp;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_layout);
}
}
Файл інтерфейсу називається second_layout.xml, тому за замовчуванням для нього створюватиметься ресурс R.layout.second_layout. Відповідно, щоб його використовувати, ми передаємо його до методу setContentView. У підсумку ми побачимо на екрані таке:

Отримання та управління візуальними елементами в коді
Вище визначений елемент TextView має один дуже важливий атрибут - id або ідентифікатор елемента. Цей ідентифікатор дає змогу звертатися до елемента, який визначено у файлі xml, з коду Java. Наприклад, перейдемо до класу MainActivity і змінимо його код:
package com.example.viewapp;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// встановлюємо як інтерфейс файл second_layout.xml
setContentView(R.layout.second_layout);
// отримуємо елемент textView
TextView textView = findViewById(R.id.header);
// перевстановлюємо в нього текст
textView.setText("Hello from Java!");
}
}
За допомогою методу setContentView() встановлюється розмітка з файлу second_layout.xml.
Інший важливий момент, який варто відзначити - отримання візуального елемента TextView. Оскільки в його коді ми визначили атрибут android:id, то через цей id ми можемо його отримати.
Activity має метод findViewById(). У цей метод передається ідентифікатор ресурсу у вигляді R.id.[ідентифікатор_елемента]. Цей метод повертає об'єкт View - об'єкт базового класу для всіх елементів, тому результат методу ще необхідно привести до типу TextView.Далі ми можемо щось зробити з цим елементом, у цьому разі змінюємо його текст.
Причому що важливо, отримання елемента відбувається після того, як у методі setContentView було встановлено розмітку, в якій цей візуальний елемент було визначено.
І якщо ми запустимо проект, то побачимо, що TextView виводить новий текст:
