Фреймворк Android

&nbsp

СТВОРЕННЯ ВИДУ

В Android існує чимало вимог, дотримання яких неминуче призводить до ускладнення внутрішньої організації призначеного для користувача інтерфейсу Інтерфейс користувача в Android – це многопроцессность система, що підтримує безліч паралельно виконуваних додатків, приймаюча різноманітні варіанти введення, виключно інтерактивна і досить гнучка для того, щоб підтримувати найрізноманітніші пристрою як в даний час, так і в майбутньому Інтерфейс користувача Android одночасно є і насиченим, і простим у зверненні

Будуть розглянуті прийоми реалізації графічного інтерфейсу користувача в Android Тут буде пояснена архітектура інструментарію для написання користувальницьких інтерфейсів Android, на практичних прикладах буде показано, як використовуються найпростіші елементи інтерфейсу, зокрема кнопки та текстові поля Крім того, тут ми поговоримо про обробку подій, використанні декількох потоків для розвантаження довготривалих завдань, щоб користувальницький інтерфейс не зависав, і торкнемося інших питань, які допомагають зробити користувальницький інтерфейс красивим і ефективним

АРХІТЕКТУРА графічний інтерфейс користувача в ANDROID

Середа Android додає в екосистему Java ще один інструментарій для створення графічних користувацьких інтерфейсів, додатково до AWT, Swing, SWT, LWUIT та ін Якщо ви працювали з якими-небудь з цих технологій, фреймворк для користувача інтерфейсу Android здасться вам знайомим Як і вищеперелічені системи, він однопотоковий, подієво-керований і заснований на бібліотеці вкладених один в одного компонентів

Фреймворк користувача інтерфейсу Android, як і інші фреймворки користувача інтерфейсів Java, організований на базі поширеного патерну «Модель-вид-контролер», який схематично зображено на рис 71 Тут надаються інструменти і забезпечується структура для побудови контролера, обробного користувача введення (наприклад, натискання клавіш або дотику до екрану), а також виду, який відображає на екрані графічну інформацію

Рис 71 Концепція «Модель-вид-контролер»

Модель

Модель – це сутність вашої програми, то, чим фактично займається програма Наприклад, модель може являти собою базу даних музичних файлів, записаних на вашому пристрої, і код для відтворення музики Або це може бути ваш список контактів і код для здійснення телефонних дзвінків, а також відправлення миттєвих повідомлень В цілому, моделі присвячена значна частина наступного матеріалу книги

У той час як вид і контролер окремо взятого додатка обовязково будуть відображати властивості моделі, з якою вони працюють, окремо взята модель може використовуватися декількома додатками Розглянемо, наприклад, МР3-плеєр і додаток, що перетворює файли формату МР3 в формат WAV Модель обох додатків включає в себе формат файлів МР3 Однак у першому додатку є звичні елементи управління у вигляді кнопок «Стоп», «Пуск» і «Пауза», і воно відтворює звуки Друге може не видавати взагалі ніяких звуків Зате у нього будуть елементи для керування таким показником, як швидкість передачі інформації (Бітрейт) Модель – це, в першу чергу, сутність для роботи з даними

Вид

Вид – це візуалізація моделі В якості загального визначення вигляд можна охарактеризувати як частина додатки, що відповідає за виведення зображення, відправку аудіоінформації в динамік, генерування відгуку на дотик і т д Графічна частина фреймворка користувача інтерфейсу Android, реалізується як дерево підкласів класу View Графічно кожен обєкт являє собою прямокутну область на екрані, яка повністю вписана в прямокутну область свого батьківського елемента в дереві підкласів Корінь цього дерева – це вікно програми

Наприклад, образотворчим компонентом гіпотетичного МР3-плеєра може бути ескіз обкладинки альбому, композиція з якого зараз відтворюється Інший вид може відображати назву пісні, що відтворюється в даний момент, а третій – містити більш дрібні види, наприклад кнопки «Стоп», «Пуск» і «Пауза»

Фреймворк користувача інтерфейсу наповнює екран зображеннями, проходячи по дереву видів і наказуючи кожному компоненту отрісовани в порядку прямого обходу (алгоритм «відвідати корінь, обійти ліве поддерево, обійти праве піддерево ») Іншими словами, кожен вид отрісовиваєт себе, а потім наказує всім своїм дочірнім видам зробити те ж саме Коли відобразиться все дерево, більш дрібні, вкладені компоненти, які можна порівняти з листям дерева (і які тому відображаються в останню чергу), виявляються вище компонентів, розташованих ближче до кореня і отрісовиваємих раніше

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

Контролер

Контролер – це частина програми, що відповідає на зовнішні впливи, наприклад на натискання клавіші, на дотик до екрану, на вхідний дзвінок і т д Контролер реалізується у вигляді черги подій (event queue) Кожне зовнішнє дію представляється як унікальна подія в черзі Фреймворк по порядку видаляє події з черги і розподіляє (Диспетчир) їх

Наприклад, коли користувач натискає яку-небудь клавішу телефону, система Android генерує подія KeyEvent і додає його в чергу подій Після того як закінчиться обробка подій, що потрапили в чергу раніше, KeyEvent видаляється з черги і передається як параметр виклику методу dispatchKey Event того виду View, який обраний в даний момент

Після того як подія відправлено в компонент, який знаходиться у фокусі, цей компонент може вчинити дію, необхідне для зміни внутрішнього стану програми Наприклад, у додатку, що представляє собою МРЗ-плеєр, коли користувач натискає на екрані кнопку «Пуск / Пауза» і подія направляється до обєкта цієї кнопки, метод-обробник може оновити модель для поновлення програвання якогось вибраного раніше звукового файлу

Всі разом

Отже, ми познайомилися з усіма концепціями, необхідними для опису всієї системи користувача інтерфейсу Коли відбувається зовнішній вплив – користувач прокручує екран, перетягує елементи або натискає кнопку, або, наприклад, надходить дзвінок або МР3-плеєр досягає кінця списку відтворення, – система Android ставить подія, що представляє дана дія, в чергу подій Нарешті подія залишає чергу – за принципом «що раніше прийшло, то раніше обслуговується» – і прямує системою до придатному оброблювачу подій Оброблювач подій – часто фрагмент коду, який ви пишете для вашої програми, – реагує на подію, повідомляючи модель, що відбулася зміна стану Модель у відповідь вживає необхідну дію

Практично будь-яка зміна стану моделі вимагає відповідної зміни в вигляді Наприклад, у відповідь на натискання клавіші компонент EditText повинен відобразити тільки що введений символ в точці вставки Аналогічно в додатку «Телефонний довідник» при натисканні контакту цей контакт буде підсвічений, а контакт, який був підсвічений раніше, – померкне

Коли модель оновлює власний стан, вона практично напевно повинна буде змінити поточне відображення, щоб відобразити, таким чином, що відбулися внутрішні зміни Щоб оновити зображення на дисплеї, модель повинна повідомити фреймворк для користувача інтерфейсу про те, що якась частина зображення, присутнього на дисплеї, вже застаріла і повинна бути перемальована Запит на перемальовування – Не що інше, як інша подія, поставлене в чергу подій в тому ж фреймворці, де щойно знаходилося подія контролера Подія перемальовування обробляється в загальному порядку, як і будь-яке інше подія для користувача інтерфейсу

Рано чи пізно подія перемальовування видаляється з черги і прямує обробнику Обробником подій перемальовування є View Дерево видів перемальовується кожен вид відповідає за відображення власного стану в той момент, коли він промальовується

Щоб конкретизувати все сказане, простежимо описаний цикл в гіпотетичній програмі для відтворення МР3

1 Коли користувач натискає на екрані зображення кнопки «Пуск / Пауза», фреймворк створює нову подію MotionEvent, в якому серед іншого міститься інформація про координати точки на екрані, де сталося натискання Фреймворк ставить нову подію у хвіст поточної черги подій

2 Як було описано в підрозділі «Контролер» вище, коли подія доходить до кінця черги, фреймворк видаляє його з цієї черги і передає по дереву видів до того віджету («листу» цього дерева), який займає прямокутну область на екрані, де і відбулося натискання

3 Оскільки даний віджет являє собою кнопку «Пуск / Пауза», код додатку, що обробляє натискання кнопки, повідомляє моделі, що слід відновити відтворення звукового файлу

4 Код моделі програми починає відтворювати вибраний звуковий файл Крім того, він посилає під фреймворк для користувача інтерфейсу запит на перемальовування зображення на екрані

5 Запит на перемальовування додається в чергу подій і, нарешті, обробляється, як це описано в підрозділі «Вид» вище

6 Екран перемальовується При цьому кнопка переходить у стан «Пуск» і все знову опиняється синхронізованим

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

Необхідно загострити увагу ще на одному важливому аспекті користувача інтерфейсу Android: він однопотоковий Єдиний потік видаляє події з черги, щоб робити зворотні виклики контролера і відображати вид Це важливо з кількох причин

Найпростіше наслідок застосування однопотокового користувача інтерфейсу полягає в тому, що при координації станів виду і контролера можна обійтися без блоків synchronized Це дуже цінна оптимізація

Ще одна перевага однопотокового користувача інтерфейсу полягає в тому, що в нашому додатку кожна подія, що знаходиться в черзі, гарантовано буде оброблено повністю і саме в тому порядку, в якому воно надійшло в чергу Це може здаватися абсолютно очевидним, але за такої умови написання коду для користувача інтерфейсу значно спрощується Коли компонент користувацького інтерфейсу викликається для обробки події, ми гарантуємо, що не почнеться ніяка інша робота, повязана з призначеним для користувача інтерфейсом, поки не буде отримана відповідь на перший виклик Тобто, наприклад, якщо компонент вимагає зробити кілька змін у стані програми – кожне з яких дає відповідний запит на перемальовування частині екрана, – то гарантується, що перерисовка не почнеться до тих пір, поки програма не закінчить обробку, не виконає всіх оновлень і не поверне відповідь Коротше кажучи, зворотні виклики для користувача інтерфейсу не залежать одне від одного

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

Джерело: Android Програмування на Java для нового покоління мобільних пристроїв

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*