Розташування

Розташування визначає візуальну структуру для користувацького інтерфейсу, такі як UI для activity або app віджету. Ви можете декларувати розташування двома шляхами:

  • Декларувати елементи UI в XML. Android провадить прямолінійний словник XML, що відповідає класам View, та його підклассам, таким, як для віджетів та розташувань.
  • Утворення елементів розташування під час роботи. Вашу застосування може створити об’єкти  View та ViewGroup (та маніпулувати іх властивостями) прграмним шляхом.

Фреймворк Android надає вам гнучкість використання той чи інший, або обоє з ціх методів, для декларації та управління UI вашого застосування. Наприклад, ви можете декларувати розташування елементи вашого інтерфейсу по замовченню в XML, включаючи елементи екрану, що мають на ньому з’являтись, та їх властивості. Тоді ви можете додати код в ваше застосування, що буде змінювати стан об’єктів екрану, включаючи в ті, що декларовані в  XML, під час виконання.

Перевага декларувати ваш UI в XML полягає в тому, що дозволяє вам краще розділити презентацію вашого додатку від коду, що контролює його поведінку. Ваші дескриптори UI є зовнішними до вашого коду додатку, що означає, що ви зможете змінити або адаптувати його, без того, щоб змінювати або адаптувати ваш первинний код та ре-компілювати його. Наприклад, ви можете створити  XML розташування для різноманітних орієнтацій екрану, різних розмірів екрану, та різних мов. Додатково, декларування розташування в XML робить простішим відтворення структури вашого UI, так що є простішим відлагоджувати проблеми. Таким чином цей документ фокусується на тому, яу ви декларуєте ваше розташування в XML. Якщо ви зацікавлені в створенні об’єктв View під час виконання, посилайтесь на документації класів ViewGroup та View.

Взагалі словник XML для декларації елементів UI близько слідує структурі та іменуванню класів та методів, де імена елементів відповідають іменам класів та імена атрибутів відповідають методам. Фактично, відповідність часто така пряма, що ви можете здогадатись, якому XML атрибуту відповідає клас методу, або здогадатись, який клас відповідає наданому XML елементу. Однак зауважте, що обоє словники не є ідентичними. В деяких випадках є деякі невеликі відміності. Наприклад, елелмент EditText має атрибут text, що корелює до EditText.setText().

Підказка: Вивчіть більше щодо різних типів розташувань, згідно з Загальними об’єктами розташувань. Також є набір інструкцій по збудуванню різноманітних розташувань в прикладі Hello Views.

Написання XML


Використовуючи словник Android XML, ви можете швидко створити розташування UI та відобразити елементи, що там містяться, в такому ж стилі, як створюються 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,  в каталзі Android проекту res/layout/, так що він буде правильно скомпільований.

Більше інформації щодо синтаксису файлу XML розташування  містить документ Ресурси розташування.

Завантаження ресурсу XML


Коли ви компілюєте ваше застосування, кожний файл розташування XML компілюється в ресурс View. Ви маєте завантажити ресурс розташування в вашому коді застосвання, в вашій реалізації зворотнього виклику Activity.onCreate(). Робіть це за допомогою виклику  setContentView(), надаючи йому посилання на ваш ресурс розташування в формі: R.layout.layout_file_name. Наприклад, якщо ваше розташування XML збережено як  main_layout.xml, вам належить завантажувати його для вашої Activity наступним чином:

public void onCreate(Bundle savedInstanceState) {
   
super.onCreate(savedInstanceState);
    setContentView
(R.layout.main_layout);
}

Метод зворотнього виклики onCreate() в вашій Activity викликається фреймворком Android, коли запускається ваша Activity (дивіться дискусію щодо життєвого циклу в документі Activities).

Атрибути


Кожний об’єкт View та ViewGroup підтримують свої власні різовиди XML атрибутів. Деякі атрибути специфічні для об’єкту View (наприклад, TextView підтримує атрибут textSize), але ці атрибути також успадковані любим об’єктом View, що може розширювати цей клас. Деякі є загальними для всіх об’єктів View, оскільки вони успадковані від кореневого класу View (як атрибут id). Також інші атрибути визначені як "переметри розташування", що є тими атрибутами, що описують певні орієнтації об’єкту View, як визначено в батьківському об’єкті  ViewGroup.

ID

Любий об’єкт View може мати цілий ID, асоційований з ним, щоб унікально ідентифікувати View в дереві. Коли застосування буде скомпільовано, цей ID посилається як ціле, але ID типово присвоєне до файлу розташування XML як рядок, з атрибуотом id. Це атрибут XML, загальний до всіх об’єктів View (визначений в класі View), та ви будете його використовувати дуже часто. Синтаксис для ID в тегах XML наступний:

android:id="@+id/my_button"

Символ @ на початку рядка вказує на те, що парсер XML має робити розбір та розширяти залишок радка ID та ідентифікувати як ID ресурс. Символ + позначає, що це нове ім’я ресурсу, що має бути створене та додане до наших ресурсів  (у файлі R.java). Є декілька інших ID ресурсів, що надаються фреймворком Android. Коли посилаєтесь на ресурсний ID Android, вам не треба символ плюса, але маєте додати простір імен android:

android:id="@android:id/empty"

З доданим іменем простору імен android, ми тепер посилаємось на ID з классу ресурсів android.R, скоріше, ніж з локального ресурсного класу.

Для того, щоб створити перегляди та посилатись на них з застосування, загальним шаблоном є:

  1. Визначити новий перегляд/віджет в файлі розташування та надайте йому унікальний ID:
    <Button android:id="@+id/my_button"
           
    android:layout_width="wrap_content"
           
    android:layout_height="wrap_content"
           
    android:text="@string/my_button_text"/>
  2. Тоді створіть екземпляр об’єкту перегляду та захопіть його з розташування (типово в методі  onCreate()):
    Button myButton = (Button) findViewById(R.id.my_button);

Створення ID для об’єктів перегляду важливо при створенні RelativeLayout. В відносному розташуванні об’єкти перегляду можуть визначати своє розташування відносно інших того ж рівня, на які посилаються через ID.

ID не має бути унікальним для всього дерева, але він має бути унікальним як частина в тій частині, де ви виконуєте пошук (що часто може бути цілим деревом, так що він має бути повністю унікальним, коли це можливо).

Параметри розташування

Атрибути XML розташування з іменами layout_something визначають параметри розташування для View, що відноситься до ViewGroup, де він розташований.

Кожний клас ViewGroup реалізує вкладений клас, який розширює ViewGroup.LayoutParams. Цей підклас містить типи властивостей, що визначають розмір та позицію для кожного дочірнього перегляду, відповідно до групи переглядів. Як ви можете бачити на Мал.1, батківська група переглядів визначає параметри для кожного дочірнього перегляду (включаючи дочірні групи переглядів).

Мал. 1. Візуалізація ієрархії переглядів з параметрами перегляду, асоційованити з кожним переглядом.

Зауважте, що кожний підклас LayoutParams має свій власний синтаксис для встановлення значень. Кожний дочірній елемнет мусить визначити LayoutParams, що пристає до його батьківського контейнеру, зауважуючи, що він також може визначати різні LayoutParams для своїх власних дітей.

Всі групи переглядів включають ширину та висоту, (layout_width та layout_height), та кожний перегляд потребує визначати їх. Багато LayoutParams також включають додаткові відкраї та контури.

Ви можете задати ширину та висоту в точних вимірах, але вважається що ви не будете бажати робити це часто. Частіше ви будете використовувати одну з ціх констант для встановлення ширини та висоти:

  • wrap_content вказує вашому перегляду визначити власний розмір як такий, до достатній для вмісту.
  • match_parent (до API Level 8 називане  fill_parent) наказує вашому перегляду бути такім великим, як може дозволити батьківська група переглядів.

Загалом, вказуючи ширину та висоту розташування з використанням абсолютних значень, таких, як пікселі, не є рекомендованим. Замість цього, використання відносних вимірювань, як незалежних від розрішення одиниць пікселів (dp), wrap_content, або match_parent, є кращим підходом, оскільки це допомагає впевнитись, що ваше застосування буде відображуватись непогано на різномаїтті різних розмірів екрана. Допустимі типи вимірів взначено в документі  Доступні ресурси.

Позиція розташування


Геометрія перегляду є прямокутником. Перегляд моє положення, виражене як пара координат left та top, та два виміри, виражені як ширина та висота. Одиниці виміру для положення та розміру є пікселі.

Можливо отримати розміщення перегялду, викликаючи методи getLeft() та getTop(). Перший повертає лівий край, або X координату прямокутника, що представляє перегляд. Інший повертає верхній край, або коордоинату  Y прямокутника, що представляє перегляд. Ці методи обоє повертають положення перегляду відносно батьківського контейнеру. Наприклад, коли getLeft() повертає 20, це означає, що перегляд розміщено на 20 пікселів справа від лівого краю батьківського контейнеру.

На додаток, запропоновано декілька зручних методів, щоб запобігти непотрібним обчисленням,  такі як getRight() та getBottom(). Ці методи повертаюсь координати правого та нижнього країв прямокутника, що представляє перегляд. Наприклад, виклик getRight() є подібним до того, щоб виконати обчислення getLeft() + getWidth().

Розмір, відступи та відкраї


Розмір перегляду виражений його шириною та висотою. Перегляд, насправді, має дві пари значень ширини та висоти. 

Перша пара відома як виміряна ширина та виміряна висота. Ці розміри визначають, як перегляд бажає біти відображеним в батьківстькому контейнері. Виміряні розміри можуть бути отримані через виклики getMeasuredWidth()та  getMeasuredHeight().

Друга пара відома як просто ширина та висота, або іноді як ширина та висота малювання. Ці розміри визначають дійсні розміри перегляду на екрані, на час малючання та після розташування. Ці значення можуть, але не повинні, відрізнятись від виміряних ширини та висоти. Ширина та висота можуть бути отримані за допомогою викликів getWidth() та getHeight().

Щоб виміряти свої розміри, перегляд бере до уваги власні відступи. Відступи визначаються в лівому, верхньому, правому та нижньому  частинах перегляду. Відступ може бути використане для зміщення вмісту перегляду на задане число пікселів. Наприклад, лівий відступ рівний 2 буде заштовхувати вміст перегляду на 2 пікселі вправо від лівого краю. Відступ може бути встановлений з використанням методу  setPadding(int, int, int, int), та опитаний за допомогою  getPaddingLeft(), getPaddingTop(), getPaddingRight() та  getPaddingBottom().

Навіть зважаючи на те, що перегляд може визначити власні відступи, він не може провадити жодної підтримки для відкраїв. Однак, цю підтримку виконують групи переглядів. Посилайтесь на ViewGroup та ViewGroup.MarginLayoutParams для подальшої інйрмації.

Для додаткової інформації щодо розмірів, дивіться Значення розмірів.

Загальні розташування


Кожний підклас класу ViewGroup проавдить унікальний шлях для відображення переглядів, що містяться в ньому. Нижце наводяться найбільш загальні типи розташувань, що вбудовані в пратформу Android.

Зауваження: Хоча ви можете вкласти один або більше розташувань в інше розташування, щоб застосувати ваш дизайн UI, вам слідує намагатись утримувати вашу ієрархію розташувань такою поверхневою, наскільки це можливо. Ваше розташування малюється швидше, якщо ви маєте менше вкладених розташувань (широка ієррахія переглядів краща, ніж глибоко вкладена ієрархія).

Linear Layout

Розташування, що організує своїх дітей в один горизонтальний або вертикальний рядок. Він створює лінійку прокручування, якщо довжина вікна перевищує довжину екрана.

Relative Layout

Дозволяє вам вказати розміщення дочірніх елементів відносно одного до іншого (елемент A зліва до B), або відносно до батіківського (вирівнено до верхнього краю батька).

Web View

Відображує веб сторінки.

Побудова розташувань за допомогою Adapter


Коли вміст вашого розташування є динамічним або невідомим заздалегідь, ви можете використовувати підкласи AdapterView щоб завантажувати дані в розташування під час виконання. Підклас класу AdapterView використовує Adapter щоб прив’язати дані до свого розташування. Adapter поводиться як посередник між джерелом даних та AdapterView —  Adapter отримує дані (від джерела, такого як масив або запит до даних), та перетворює кожне входження в перегляд, що може бути доданий до розташування AdapterView.

Загальні розташування на базі адаптерів включають:

List View

Відображує прокручуваний список в один стовпчик.

Grid View

Відображує прокручувану сітку стовпчиків та рядків.

Заповнення перегляду адаптеру даними

Ви можете заповнювати AdapterView, такі як ListView або GridView через прив’язування  екземпляру AdapterView до Adapter, що отримує дані з зовнішнього джерела, та створює View , що представляє кожне входження даних.

Android провадить декілька підкласів Adapter, що є корисним для отримання різних типів даних, та побудови перегляду для AdapterView. Два найбільш загальні адаптери є наступні:

ArrayAdapter
Використовуйте цей адаптер, коли ваше джерело даних є масивом. По замовчанню ArrayAdapter створює перегляд для кожного елементу масива, викликаючи toString() для кожного елелменту, та розміщуючи вміст в якості TextView.

Наприклад, якщо ви маєте масив з рядків, що ви бажаєте відобразити як ListView, ініціалізуйте новий  ArrayAdapter з використанням конструктору для завдання розташування для кожного рядка та масиву рядків:

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
        android
.R.layout.simple_list_item_1, myStringArray);

Аргументи до цього конструктору наступні:

  • Ваш Context
  • Розташування, що містить TextView для кожного рядка в масиві
  • Масив рядків

Тоді просто викликати setAdapter() для вашого ListView:

ListView listView = (ListView) findViewById(R.id.listview);
listView
.setAdapter(adapter);

Щоб налаштувати вигляд для кожного елементу, ви можете перевизначити метод  toString()для об’єктів вашого масиву. Або, щоб створити перегляд для кожного елементу, що є дещо іншим, ніж TextView (наприклад, якщо ви бажаєте ImageView для кожного елементу масива), розширюйте клас ArrayAdapter та переозначте getView(), щоб повернути тип перегляду, який ви бажаєте для кожного елементу.

SimpleCursorAdapter
Використовуйте цей адаптер, коли ваші дані приходять з  Cursor. Коли використовується  SimpleCursorAdapter, ви повинні вказати розташування, що треба застосовувати для кожного рядка з Cursor, та які стовпчики з Cursor мають бути вставлені в які перегляди з розташування. Наприклад, якщо ви бажаєте створити список людей з імен та номерів телефонів,  ви можете виконати запит, що повертає Cursor, що містить рядок для кожної людини та стовпчики для для імен та номерів. Тоді ви створюєте масив з рядків, що містять стовпчики, які вказують, які стовпчики з Cursor ви бажаєте мати в розташуванні для кожного результату, та масив цілих, вказуючий, на відповідні перегляди, де мають розміщені кожний з стовчиків:

String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME,
                       
ContactsContract.CommonDataKinds.Phone.NUMBER};
int[] toViews = {R.id.display_name, R.id.phone_number};

Коли ви реалізуєте  SimpleCursorAdapter, передайте розташування для використання з кожним результатом, Cursor, що містить результати, та ці два масиви:

SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
        R
.layout.person_name_and_number, cursor, fromColumns, toViews, 0);
ListView listView = getListView();
listView
.setAdapter(adapter);

Тоді SimpleCursorAdapter створює перегляд для кожного рядка в Cursor з використанням наданого розташування, включаючи кожний елемент fromColumns в відповідний перегляд  toViews.

Якщо, впродовж життєвого циклу вашого застосування, ви зміните підпорядковані дані, що читає ваш адаптер, вам слідує викликати notifyDataSetChanged(). Це поінформує приєднаний перегляд, що дані були змінені, та що вони мають оновитись самостійно. 

Обробка подій клацань

Ви можете відповідати на події клацання на кожному елементі AdapterView, реалізуючі інтерфейс AdapterView.OnItemClickListener. Наприклад:

// Створити об’єкт обробки повідомлення як анонімного класу
private OnItemClickListener mMessageClickedHandler = new OnItemClickListener() {
   
public void onItemClick(AdapterView parent, View v, int position, long id) {
       
// Зробити щось на відгук від клацання
   
}
};

listView
.setOnItemClickListener(mMessageClickedHandler);