неділя, 19 лютого 2017 р.

Activity (Android)

В Android основні елементи програми - активності (Activity) та макети (Layout).

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

Макет – це файл опису графічного інтерфейсу користувача в форматі XML.
 
Рекомендують називати файли активності використовуючи слово Activity, наприклад, HelloActivity, StartActivity і т.п. Макети називаються з малої букви, із словами у зворотньому порядку, з використанням символу підкреслення між словами. При використанні Android Studio макети автоматично найменуються, наприклад, activity_hello, activity_start.

Завдання:
Розробити програму, яка б складалася з однієї активності та містила кнопку(Button) і текстове поле(TextView). При натисненні кнопки напис текстового поля повинен змінитися на інший.

Рис. 1 - Результати виконання програми

Створення заготовки

Щоб створити заготовку програми достатньо скористатися готовими шаблонами в Android Studio. Вибираємо File.>new->New Project і вибираємо серед запропонованих шаблонів Blank Activity. Називаємо наш проект FirstApp, і при бажанні вводимо назву пакету і тиснемо фініш. В результаті буде створений проект, який просто буде виводити на екран «Hello, World!!!». Нас в даному проекті цікавить три файли.

1. Клас активності 

Якщо ви не вводили власну назву, то він буде називатися MainActivity (див. в папці java) і виглядатиме десь так:

package ua.kyiv.volodimirg.firstapp;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;


public class MainActivity extends AppCompatActivity {
        @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }
}


Клас AppCompatActivity – це підклас Activity для старіших версій Android. При створенні проекту було вибрано сумісніть з API 17.
.
Метод onCreate – це основний метод з якого починається виконання активності. Це свого роду аналог точки входу void main() в звичайній java програмі.

2. Файл макету

По замовчуванню він матиме назву activity_main.xml (див. каталог res/layout)/

Виглядатиме десь так:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="ua.kyiv.volodimirg.firstapp.MainActivity">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hello World!"/>

</RelativeLayout>
3. Файл Strings.xml

Даний фaйл призначений для зберігання текстових рядків, зокрема, назв кнопок, написів в текстових полях і т.п (див. каталог res/values). Виглядатиме десь так:
<resources>
    <string name="app_name">FirstApp</string>
</resources>
У використаному стандартному шаблоні Android Studio у даному файлі зберігається назва нашого застосунку. Даний файл дозволяє управляти усіма нашими написами у програмі. Можна написи вставляти і всередині java коду, проте такий підхід обіцяє багато проблем у майбутньому, коли потрібно буде міняти написи і локалізувати програми для іншомовних користувачів.

Розглянемо більш детальніше структуру проекту та що це все означає.

Макет (Layout)

В Android Studio макет можна створювати в двох режимах: графічному та текстовому. Проте як не намагатися, в графічному режимі розміщати елементи, усе рівно доводиться підправляти макет в текстовому режимі. В макетах використовується поняття видів (view) – це графічні елементи користувача як то кнопки, списки і т.д.

Примітка. В перекладній літературі по програмуванню під Android зустрічається види також називають віджетами, та й навіть англомовні програмісти не завжди розрізняють дані терміни. Часто виділяють, що види – це найпростіші елементи (кнопки, списки і т.д.), а віджети більш складніші і складаються з простих елементів, тобто це групи простих елементів. Часто під віджетами розуміють готові мініатюрні програми. Плутанину також ввели розробники елементів в Android оскільки частина видів знаходиться у пакетах в назвах яких є слово widget.

При створенні макету спочатку визначають схему розміщення, за яку відповідають спеціальні елементи, що здатні вміщати інші View елементи: LinearLayout, FrameLayout, TableLayout, RelativeLayout. Кожен з цих віджетів є нащадком класу ViewGroup. При використанні видів використовується поняття кореневого виду та потомків. Потомком (сhild) називають вид, що вміщується всередині іншого виду.

Примітка. По суті LinearLayout, FrameLayout та ін. – це свого роду аналоги менеджерів розташування (Layout Managers) у стандарній java бібліотеці Swing. Вони вказують на порядок розміщення елементів в них. Щоправда, на відміну від менеджерів стандартної java бібліотеки Swing, дані елементи у Android є одночасно і аналогами панелей для розміщення інших елементів. У Swing спочатку створюється панель(JPanel), потім їй назначається менеджер і вже тоді вносяться елементи. У Android у макеті достатньо лише визначити який віджет для розміщення використовувати і вносити у нього елементи.

В структурі Android проекту, активності розміщуються у папці java, а макети розміщуються у res/ layout.
Рис.2 – Основні файли проекту (перегляд в режимі Android,
див. список зверху із значком андроїда) 

Деякі атрибути видів
 
android:layout_width та android:layout_height – задають ширину і висоту елемента. Переважно мають два значення:

- match_parent – розміри визначаються розмірами батьків;

- match_content – розміри визначаються розмірами вміст.

Раніше використовувалося значення fill_parent – це значення вважається застарілим і еквівалентне match_parent.

android:text – атрибут, що використовується у TextView та Button для задання тексту. Текст може вписуватись безпосередньо в лапках android:text="hello", проте такий стиль не рекомендується, оскільки при великій кількості надписів їх важко контролювати та й інтернаціоналізацію проекту важку робити. Тому тексові значення прийнято розміщати в окремому файлі strings.xml (в папці res/values). При цьому в самому елементі пишуть "@string/hello_text". Тоді у файлі string.xml повине бути рядок:

 <string name="hello_text">hello_world</string>

android: orientation – орієнтація елементів (по вертикалі чи горизонталі)

Старт активності
 
Активність почитає виконуватись із методу onCreate().

Тут вписуються дії при старті програми.
setContentView(R.layout.activity_main);
даний рядок здійснює заповнення(inflates) графічного інтерфейсу користувача, при цьому макет пов’язується з нашою активністю. R.layout.activity_main – це ідентифікатор нашого ресурсу.

Ресурси

Ресурсом називають частину застосунку, що не є кодом (файли XML, рисунки, тощо). Макет – це приклад ресурсу. Макети знаходяться в каталогах res/layout/, рядкові змінні знаходяться у res/values/. Для звернення до ресурсу використовується спеціальні ідентифікатори ресурсу, які генеруються автоматично. Щоб подивитися на ідентифікатори ресурсу, потрібно переключитися в Android Studio в режим перегляду Project і в каталозі app/build/generated/source/r/debug потрібно знайти файл R.java. Даний файл генерується автоматично при розгортанні проекту і в нього не варто вносити, якісь зміни. Незабудьте перемкнутись назад в режим Android в Android Studio. В цьому режимі простіше працювати з основними файлами проекту.

Рис. 3. – Перемикання режиму перегляду

Одержання посилання на об’єкт View

Повернемось до нашого завдання, щоб обробити натиснення кнопки і щоб змінити напис текстового поля, нам потрібно отримати посилання на ці об’єкти (ідентифікатори об’єктів).

Спочатку модифікуємо дизайн і розмістимо там кнопку, крім текстового поля. Далі присвоїмо ідентифікатори (id) нашим елементам. Таким чином activity_main.xml матиме вигляд:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="ua.kyiv.volodimirg.firstapp.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/start_message"
        android:id="@+id/hello_message"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/button_text"
        android:id="@+id/hello_button"
        android:layout_marginTop="60dp"
        android:layout_below="@+id/textView"
        android:layout_centerHorizontal="true"/>
</RelativeLayout>
Вміст Strings.xml
<resources>
    <string name="app_name">FirstApp</string>
    <string name="start_message">Місце для повідомлення</string>
    <string name="hello_message">Привіт, Світе!</string>
    <string name="button_text">Сказати привіт!</string>
</resources>
Далі в нашій активності MainActivity потрібно створити змінні, щоб тримали посилання на об’єкти кнопки та текстового поля:
private Button mHelloButton;
private TextView mHelloMessage;
Отримати посилання на кнопку можна таким чином у методі onCreate():
mHelloButton = (Button) findViewById(R.id.hello_button);
Щоб замінити текст нашого TextView, можна написати:
mHelloMessage = (TextView) findViewById(R.id.hello_message);
mHelloMessage.setText(R.string.hello_message);
Метод findViewById() використовує файл R, про який йшлося вище для пошуку посилань.

Обробка подій

Тепер потрібно модифікувати текст активності, щоб здійснювалася обробка натиснення кнопки. Обробка подій в Android здійснюється аналогічно до обробки подій в Java програмах. Спочатку призначаємо обробника подій (слухача подій), далі пишемо текст даного обробника. Обробник подій може бути окремим класом, або ж реалізований анонімним класом прямо в тексті активності.

Так, щоб обробити нашу події(натиснення кнопки) в анонімному класі пишемо:
mHelloButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mHelloMessage = (TextView) findViewById(R.id.hello_message);
        mHelloMessage.setText(R.string.hello_message);
    }
});
Вцілому MainActivity повинен виглядати так:

package ua.kyiv.volodimirg.firstapp;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    private Button mHelloButton;
    private TextView mHelloMessage;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mHelloButton = (Button) findViewById(R.id.hello_button);
        mHelloButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mHelloMessage = (TextView) findViewById(R.id.hello_message);
                mHelloMessage.setText(R.string.hello_message);
            }
        });
    }
}
Усе далі запускаємо нашу програму на емуляторі або ж на реальному пристрої і насолоджуємось нашим творінням.

Рекомендована література
 
Bill Phillips, Chris Stewart, Brian Hardy & Kristin Marsicano. Android Programming. The Big Nerd Ranch Guide. 2nd Edition. 2015.