Денис Колисниченко



Pdf просмотр
страница4/8
Дата05.11.2016
Размер5.05 Kb.
Просмотров1995
Скачиваний0
1   2   3   4   5   6   7   8







Позже мы этот файл рассмотрим подробнее, а пока вам достаточно знать, для чего он используется.
4.2. Компоненты Android-приложения
Если вы программировали на языке C, то знаете, что у C-приложения есть одна точка входа (entry point) — функция main()
. У Android-приложения нет единствен- ной точки входа. Android-приложение состоит из компонентов, которые система может запускать, когда ей это необходимо. Одно приложение может также вызы- вать компоненты другого приложения, если, конечно, приложение разрешило ис- пользование своих компонентов.
Всего существует четыре типа компонентов:
Activity
— деятельность;
Service
— служба;
ContentProvider
— контент-провайдер;
BroadcastReceiver
— приемник широковещательных намерений.
П
РИМЕЧАНИЕ
Намерения — это асинхронные сообщения, активирующие деятельности, службы и приемники широковещательных намерений. Намерение — это объект класса Intent, представляющий собой содержание сообщения.

78
Часть II. Базовое программирование для Android
Рассмотрим эти компоненты подробнее.
Начнем с первого компонента —
Activity
. Деятельность (активность) представ- ляет собой визуальный интерфейс пользователя, т. е., попросту говоря, окно.
Окно обычно заполняет весь экран мобильного устройства, но может быть меньших размеров, чем экран устройства.
Если у приложения несколько окон, то у него будет несколько деятельностей.
Каждая деятельность независима от других, при открытии новой деятельности
(нового окна) работа предыдущей деятельности приостанавливается.
У следующего компонента приложения — службы (
Service
) — нет графическо- го интерфейса пользователя. Служба
1
выполняется в фоновом режиме до тех пор, пока не завершит свою работу.
Другие приложения могут подключаться к службе. После подключения к служ- бе вы можете использовать функции, предоставляемые службой. Приложение может также запустить или остановить службу.
Для получения информации о внешних событиях и реакции на них служит ком- понент
BroadcastReceiver
. Источником события могут быть службы и другие приложения. Приложение может реагировать на любые события, которые оно посчитает важным.
У приемников широковещательных намерений нет пользовательского интер- фейса, но в ответ на событие они могут запустить деятельность, т. е. отобразить окно.
Следующий компонент приложения — контент-провайдер (
ContentProvider
).
Он служит для предоставления доступа к данным программы другим приложе- ниям. Данные программы могут храниться как в файловой системе, так и в базе данных SQLite (могут быть и другие способы хранения данных).
4.3. Процессы в ОС Android
Если хотя бы один компонент приложения будет востребован, ОС Android запустит процесс, содержащий единственный основной поток для выполнения. Все компо- ненты приложения работают в этом процессе и потоке.
Однако это поведение по умолчанию. Вы можете сделать так, чтобы компоненты работали в других процессах и порождали дополнительные потоки, т. е. создать многопотоковое приложение. В случае нехватки памяти операционная система мо- жет завершить процесс, если нужно выделить память более важным процессам.
Компоненты, выполняющиеся в этом процессе, будут уничтожены.
Но какой процесс можно уничтожить, а какой нельзя? Согласитесь, будет некраси- во, если Android уничтожит процесс, с которым пользователь работает в данный момент. Поэтому Android оценивает важность процесса с точки зрения пользовате-
1
Подробно о службах мы поговорим в главе 11.

Глава 4. Основы построения приложений
79 ля. Операционная система никогда не уничтожит видимый пользователем компо- нент процесса, но может завершить процесс с невидимыми деятельностями, кото- рые более не отображаются на экране. Также может быть завершена служба, вы- полняющаяся в другом процессе.
Какой процесс будет завершен в первую очередь, зависит от его приоритета. У ак- тивного процесса критический приоритет, поэтому он не может быть завершен, у видимого и сервисного процесса высокий приоритет, поэтому система, скорее всего, его тоже не завершит. Главными кандидатами на завершение являются про- цессы с низким приоритетом — фоновые и пустые процессы. Сначала система уда- лит пустые процессы, затем — фоновые.
Думаю, с приоритетами все ясно, но нужно разобраться с терминологией.
Актив- ным процессом (Foreground Process) называется процесс, с которым в данный мо- мент работает пользователь. Система считает процесс активным, если процесс вы- полняет деятельность, с которой работает пользователь, или же процесс выполняет службу, которую использует активная деятельность. Заметьте, что процесс А может выполнять службу, которая используется деятельностью, выполняющейся процес- сом Б. С этой деятельностью работает пользователь, поэтому процессы А и Б счи- таются активными.
Также процесс считается активным, если он имеет объект Service и выполняется один из методов обратного вызова, который определен в этом объекте. Если про- цесс имеет объект Broadcast Receiver и выполняется его метод обратного вызова для приема намерения, то процесс тоже считается активным.
Активные процессы система может удалить только в том случае, если памяти оста- лось так мало, что все активные процессы уже не могут выполняться одновре- менно.
Видимым (Visible Process) называется процесс, не имеющий никаких приоритетных компонентов. Например, процесс А запустил деятельность не на весь экран. Поль- зователь работает с процессом Б, который также отображает активность. Актив- ность процесса А не имеет фокуса, но все еще видна пользователю, поэтому про- цесс А называется видимым. Также видимым считается процесс, выполняющий службу, которая связана с деятельностью, находящейся на переднем плане, но не активна или частично закрыта другой деятельностью.
Сервисным (Service Process) называется процесс, в котором выполняется служба и который не относится к активным и видимым. Обычно сервисные процессы не имеют интерфейса, но они выполняют задания, необходимые пользователю, — на- пример, сервисным процессом может считаться фоновая работа проигрывателя.
Поэтому система старается сохранить сервисные процессы.
Фоновым (Background Process) считается процесс, в котором выполняется деятель- ность, которая в данный момент не видна пользователю. Фоновый процесс может быть уничтожен в любой момент, если понадобилась память активному, сервисно- му или видимому процессу.
Пустой (Empty Process) процесс вообще не содержит активных компонентов при- ложения. Система использует такие процессы в качестве кэша — для более быст-

80
Часть II. Базовое программирование для Android рой последующей инициализации компонентов приложения. Однако если понадо- бится память, то такие процессы будут удалены в первую очередь.
4.4. Подробнее о файле AndroidManifest.xml
Перед запуском компонента операционная система должна убедиться, что он суще- ствует. Для описания компонентов используется файл
AndroidManifest.xml
. У каждого
Android-приложения есть свой файл манифеста — даже у самых простых прило- жений.
В файле манифеста указываются имя Java-пакета приложения (имя пакета исполь- зуется в качестве уникального идентификатора приложения), разрешения, которы- ми должно обладать приложение для обращения к защищенным частям API (нужно для взаимодействия с другими приложениями), библиотеки, необходимые для вы- полнения этого приложения, и т. д.
Но самое главное — это описание компонентов приложения, а именно деятельно- стей, служб, контент-провайдеров и т. д. Объявления в файле манифеста позволяют операционной системе узнать, чем является тот или иной компонент и при каких условиях он должен быть запущен.
В среду Eclipse встроен редактор файла манифеста. Для его запуска щелкните двойным щелчком на файле
AndroidManifest.xml в окне Package Explorer (рис. 4.3).
Основными элементами файла
AndroidManifest.xml являются

,

и

. Остальные элементы этого файла используются при необходимости.
При желании вы можете редактировать элемент

с помощью встроен- ного редактора Eclipse (рис. 4.4).
Элемент

является корневым элементом файла
AndroidManifest.xml
. По умолчанию плагин ADT генерирует элемент

так:

Первый атрибут (
xmlns:android
) определяет пространство имен Android, этот атрибут всегда остается неизменным для всех Android-приложений.
Второй атрибут (
package
) задает имя пакета приложения, которое вы указали при создании проекта.
Третий атрибут (
android:versionCode
) задает внутренний номер версии.
Атрибут android:versionName указывает пользовательскую версию. Вы можете указать как строку, так и указатель на строковый ресурс.
Элемент

определяет минимальный уровень API, необходимый для за- пуска приложения, — т. е., по сути, определяет версию Android:


Глава 4. Основы построения приложений
81
Рис. 4.3. Редактор файла манифеста
Обычно задается один параметр этого элемента — android:minSdkVersion
. Можно также задать элемент targetSdkVersion
, задающий целевую платформу приложения.
Самый главный элемент файла манифеста —

. В этом элементе опи- сываются:

— деятельность;

— псевдоним для деятельности;

— служба;

— приемник намерений;
— контент-провайдер;

— подключаемые библиотеки.
В простом приложении, которое мы создали в предыдущей главе, элемент

представлен так:

82
Часть II. Базовое программирование для Android android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" >







В нашем случае указаны атрибуты android.icon
(пиктограмма приложения), android.label
(название приложения) и android.theme
(тема оформления прило- жения).
Рис. 4.4. Редактор элемента в Eclipse

Глава 4. Основы построения приложений
83
Элемент

описывает деятельность так: атрибут android:name задает имя класса, которое должно включать полное обо- значение пакета, но поскольку имя пакета уже определено в

, то имя класса можно записывать в сокращенном виде, что и делает плагин ADT; атрибут android:label задает текстовую метку, которая будет показана пользо- вателю.
Кроме этих атрибутов элемент

может содержать множество других, оп- ределяющих разрешение экрана, его ориентацию и т. д.
Объявляя деятельности вручную, помните, что если деятельность не описана в эле- менте

, то пользователь не сможет ее увидеть.
Следующий атрибут —

. Он определяет типы намерений, на кото- рые будут отвечать деятельность, сервис или приемник намерений. Фильтр наме- рений (как раз это и есть атрибут

) определяет, что может сделать деятельность или служба. В этом элементе могут быть дочерние элементы

,

,

: элемент

добавляет действие к фильтру намерений. В фильтре намере- ний могут быть несколько элементов

, но, как минимум, должен быть один такой элемент; в элементе

определяется категория компонента, которую должно об- работать намерение. Как правило, задаются строковые константы (в качестве имени намерения), определенные в классе
Intent
, например:
элемент

используется, чтобы добавить спецификацию данных к фильтру намерений. Спецификация может быть URL, типом данных или и URL, и типом данных.
Мы рассмотрели основные элементы файла манифеста. Остальные элементы будут описаны далее по мере необходимости.



ГЛ А В А
5

Разработка интерфейса пользователя
5.1. Разметка интерфейса
5.1.1. Файл разметки и редактор разметки
Графический интерфейс пользователя формируется с помощью объектов
View
(представление) и
ViewGroup
(группа представлений). При этом класс
ViewGroup является дочерним классом для
View
Класс
View служит основой для подклассов, которые называются виджетами.
Виджеты — это элементы пользовательского интерфейса: текстовые поля, кнопки и т. п.
Разметка интерфейса пользователя — это процесс размещения элементов интер- фейса (виджетов) для конкретного окна приложения (для конкретной деятельно- сти). Разметку можно выполнить двумя способами. Первый заключается в редакти- ровании XML-файла окна приложения. Для главного окна приложения этот файл называется res/layout/main.xml
. Такой способ поначалу вам покажется более суровым.
Начинающим программистам больше понравится второй способ — графический.
Плагин ADT предлагает очень удобный редактор разметки интерфейса пользовате- ля (рис. 5.1).
Какой способ будет рассмотрен в книге? Конечно же, первый — ручная разметка путем редактирования XML-файла. Ведь проблем с освоением редактора интер- фейса, думаю, у вас не возникнет. На практике же вы можете использовать любой способ, а структуру файла разметки мы сейчас рассмотрим, чтобы правильно вас сориентировать.
Каждый элемент файла разметки является объектом класса
View или
ViewGroup
Если представить все элементы интерфейса пользователя в виде иерархии, то объ- екты класса
ViewGroup будут ветвями дерева, а объекты класса
View
— листьями.
Иерархия созданного интерфейса отображается на вкладке Outline редактора интерфейса. На рис. 5.1 видно, что добавлены разметка
RelativeLayout
(это и бу- дет объект класса
ViewGroup
) и три кнопки (это объекты класса
View
, точнее их по- томки).


Глава 5. Разработка интерфейса пользователя
85
Рис. 5.1. Графическая разметка интерфейса пользователя
Рассмотрим файл разметки (
res/layout/activity_main.xml
) нашего первого проекта.
С этим файлом мы уже знакомы, но, чтобы не листать лишний раз книгу, для на- глядности еще раз приведу его в листинге 5.1.
Листинг 5.1. Файл разметки activity_ main.xml


86
Часть II. Базовое программирование для Android android:layout_height="wrap_content" android:text="@string/hello_world" />

В каждом файле разметки должен быть только один корневой элемент. В нашем случае таким элементом является
RelativeLayout
(относительная разметка). После определения корневого элемента вы можете добавить в него дополнительные объ- екты разметки или виджеты в качестве дочерних элементов.
Рассмотрим некоторые атрибуты элементов
LinearLayout и
TextView
: xmlns:android
— объявление пространства имен Android. Стандартный атрибут и стандартное значение для Android-приложения; android:layout_width
— ширина объекта
View или
ViewGroup
. В нашем случае объект занимает весь экран, поэтому используется значение match_parent
(это то же самое, что и значение fill_parent
, которое применялось ранее. Вы можете использовать как match_parent
, так и fill_parent
). Можно задать и значение wrap_content
— тогда ширина или высота определяются по содержимому эле- мента; android:layout_height
— высота объекта. Для этого атрибута также можно ис- пользовать значения match_parent и wrap_content
; android:text
— текст, который должен отобразить объект
TextView
. В нашем примере вместо строковой константы используется значение из файла strings.xml
— строка hello_world
. Благодаря такому приему очень легко выпол- нить локализацию приложения (перевод на другой язык).
У каждого объекта
View или
ViewGroup
— свой набор атрибутов. С ними мы позна- комимся чуть позже — когда будем рассматривать базовые виджеты.
Установить атрибуты объектов можно как с помощью файла разметки, так и в Java- коде. В большинстве случаев имя атрибута XML соответствует названию метода в классе Java. Например, для установки атрибута android:height
(задает высоту объ- екта) используется метод setHeight(int)
, для установки атрибута android:text
— метод setText(int)
и т. д. Но бывают исключения. Метод setHighlightColor(int)
служит для установки значения атрибута android:textColorHighlight
. Как видите, название метода похоже на название атрибута, но не соответствует ему полностью.
Все это говорит о том, что перед написанием Java-кода желательно обратиться к документации и не полагаться только на одну интуицию. Также при написании
Java-кода можно воспользоваться помощью среды Eclipse. Если вы забыли (или вообще не знаете!), как называется то или иное свойство или метод объекта, введи- те его имя, точку и через мгновение раскроется выпадающий список со свойствами и методами этого объекта, а также с подсказкой по выделенному методу/свойству
(рис. 5.2). Аналогичный функционал есть и в других IDE.
О Java-коде мы поговорим позже, пока же рассмотрим типы разметки.

Глава 5. Разработка интерфейса пользователя
87
Рис. 5.2. Помощь в написании кода
5.1.2. Типы разметки
Вы можете использовать один из четырех типов разметки:
FrameLayout
— разметка фрейма;
LinearLayout
— линейная разметка;
TableLayout
— табличная разметка;
GridLayout
— разметка в виде сетки;
AbsoluteLayout
— абсолютная разметка, когда указывается явная позиция на экране в системе координат (x,y);
RelativeLayout
— относительная разметка.
FrameLayout
Начнем с первой разметки.
FrameLayout
— самый простой тип разметки. Все дочер- ние элементы
FrameLayout будут прикреплены к верхнему левому углу экрана.
Этот тип разметки настолько примитивен, что даже наше простейшее приложение
(которое мы создали в главе 3) использует тип разметки
LinearLayout
. Единствен- ное применение для
FrameLayout
— это ее использование внутри ячейки таблицы
(см. далее), а для создания полноценной разметки приложения этот вариант не го- дится.
LinearLayout
Линейная разметка (
LinearLayout
) размещает виджеты горизонтально или верти- кально — в зависимости от атрибута android:orientation
: android:orientation="vertical"

88
Часть II. Базовое программирование для Android а б
Рис. 5.3. а — кнопки выровнены вертикально; б — кнопки выровнены горизонтально

Глава 5. Разработка интерфейса пользователя
89
Посмотрите на рис. 5.3, а — на нем задана линейная вертикальная разметка, поэто- му кнопки размещаются друг под другом — вертикально. Чтобы задать горизон- тальную разметку, нужно изменить атрибут так: android:orientation="horizontal"
Измените атрибут android:orientation
, затем перейдите на вкладку Graphical
Layout и вы увидите, что наши кнопки выстроились горизонтально (рис. 5.3, б).
В листинге 5.2 приведен файл разметки для интерфейса с тремя кнопками, изобра- женного на рис. 5.3, а.
Листинг 5.2. Файл разметки main.xml
>




Рис. 5.4. У последней кнопки максимальный «вес»

90
Часть II. Базовое программирование для Android
У разметки
LinearLayout есть атрибут android:layout_weight
, задающий «вес» от- дельного дочернего элемента. Чем выше «вес», тем важнее элемент. Элемент с мак- симальным «весом» займет всю оставшуюся часть родительского элемента. По умолчанию «вес» элемента равен 0. Установите для третьей кнопки «вес», отлич- ный от 0:

В результате последняя кнопка будет растянута на всю ширину экрана (рис. 5.4).
TableLayout
Разметка
TableLayout размещает виджеты в строки и столбцы — в виде таблицы.
Границы таблицы не отображаются, таблица служит не для представления данных, а сугубо для размещения виджетов.
Таблица может иметь строки с разным количеством ячеек. Для формирования строк таблицы разметки используются объекты
TableRow
. Каждый такой объект — это одна строка таблицы. В строке может вообще не быть ячеек, может быть одна или несколько ячеек. В свою очередь ячейка может быть объектом класса
ViewGroup
— другими словами, ячейка допускает разметку. То есть, в ячейку табли- цы вы можете поместить объект
LinearLayout и с его помощью разместить элемен- ты внутри ячейки. Как элемент ячейки можно использовать и другой элемент
TableLayout
— получится вложенная таблица.
Сейчас мы продемонстрируем использование табличной разметки на примере соз- дания клавиатуры для простейшего калькулятора. Создайте новый проект или от- кройте наш простой проект, разработанный в главе 3. Перейдите к редактору раз- метки (для этого откройте в структуре проекта файл
/res/layout/main.xml и щелкните на нем двойным щелчком). Затем перейдите на вкладку activity_main.xml и удали- те из XML-файла все, кроме элемента

Затем создайте разметку — для этого в группе Layouts выберите TableLayout.
В эту разметку нужно добавить четыре элемента
TableRow
. Для каждого элемента
TableRow нужно установить следующие атрибуты:
Gravity = center
;
Layout width = fill_parent
;
Layout height = wrap_content
Для этого щелкните на элементе правой кнопкой, выберите необходимый атрибут и установите нужное значение (рис. 5.5). Свойство (атрибут) Gravity, установка ко- торого показана на рис. 5.5, выравнивает элемент в контейнере — мы выбираем выравнивание по центру. В контекстном меню приведены не все свойства. Ранее
(в старой версии IDE) все свойства были собраны в подменю Properties. Сейчас часто используемые свойства выделены в контекстное меню, а некоторые другие свойства (которые используются реже) собраны в подменю Other Properties.

Глава 5. Разработка интерфейса пользователя
91
Рис. 5.5. Установка значения атрибута
Далее в каждую строку (в каждый контейнер
TableRow
) нужно добавить по четыре кнопки (кнопки находятся в группе Form Widgets). Ширину каждой кнопки нужно установить в
20pt
, но это значение зависит от типа платформы Android и от размера экрана. На рис. 5.6 представлена наша клавиатура, версия платформы — 5.0. Обра- тите внимание на иерархию графического интерфейса (вкладка Outline).
В XML-файле разметка
TableLayout будет объявлена так:

Наша клавиатура смотрится некрасиво только потому, что она расположена не по центру экрана. Чтобы она была размещена по центру (по горизонтали и по вертика- ли), установите атрибут
Gravity для
TableLayout
. В итоге в файле разметки
TableLayout будет объявлена так:

92
Часть II. Базовое программирование для Android android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center">
На экране это будет выглядеть, как показано на рис. 5.7.
Полный код XML-файла разметки клавиатуры калькулятора представлен в лис- тинге 5.3.
Рис. 5.6. Созданная клавиатура калькулятора (Android 5.0)
Листинг 5.3. Файл activity_main.xml для клавиатуры калькулятора


Глава 5. Разработка интерфейса пользователя
93 android:layout_width="fill_parent" android:gravity="center">

94
Часть II. Базовое программирование для Android android:text="-" android:layout_width="20pt"/>



Глава 5. Разработка интерфейса пользователя
95 android:layout_width="20pt" android:text="="/>

96
Часть II. Базовое программирование для Android
Вернемся к ширине кнопок. На рис. 5.7 наша клавиатура выглядит практически идеально. Увеличивать размер кнопок не нужно — ведь если вы будете создавать полноценный калькулятор, вам понадобится место для дополнительных кнопок:
MR, MC, M+, MS, CE, CE и т. д. На рис. 5.8 показано, что будет, если увеличить размер кнопок до 50 pt. Они даже не поместятся на экране при книжной ориента- ции, поэтому на рис. 5.8 ориентация экрана — альбомная.
RelativeLayout
При относительной разметке (
RelativeLayout
) позиция дочерних виджетов опреде- ляется относительно родительского элемента. При использовании этого типа раз- метки элементы графического интерфейса размещены так, что если первый элемент расположен по центру, другие элементы, выравнивание которых задается относи- тельно первого элемента, будут также выровнены по центру экрана.
Лучше всего продемонстрировать относительную разметку на примере. На рис. 5.9 изображен интерфейс пользователя: надпись, поле ввода и две кнопки. На рис. 5.10 — иерархия интерфейса. Файл разметки интерфейса представлен в лис- тинге 5.4.
Рис. 5.9. Относительная разметка

Глава 5. Разработка интерфейса пользователя
97
Рис. 5.10. Иерархия интерфейса
Листинг 5.4. Файл разметки интерфейса, изображенного на рис. 5.9




98
Часть II. Базовое программирование для Android
Более сложный пример использования относительной разметки можно найти на моем форуме: http://www.dkws.org.ua/phpbb2/viewtopic.php?p=34603#34603.

GridLayout
Этот тип разметки впервые появился в Android 4 и очень похож на
TableLayout
В проектах, адаптируемых под новые платформы (4.х и 5.x), рекомендуется исполь- зовать именно этот тип разметки. Разметка
GridLayout относится к классу android.widget.GridLayout и позволяет создавать колонки, ряды и ячейки как в
TableLayout
, но при этом элементы можно гибко настраивать. Получается, что но- вый тип разметки гораздо удобнее
TableLayout
Чтобы попробовать
GridLayout на практике, давайте воссоздадим с его помощью клавиатуру нашего калькулятора (рис. 5.11). Посмотрите, насколько элегантнее стал код (листинг 5.5). Сравните его с кодом из листинга 5.3.

Рис. 5.11. Клавиатура калькулятора с использованием GridLayout

Глава 5. Разработка интерфейса пользователя
99
Листинг 5.5. Клавиатура калькулятора с использованием GridLayout



100
Часть II. Базовое программирование для Android

Глава 5. Разработка интерфейса пользователя
101
С помощью
TableLayout организовать что-либо подобное тоже можно, но код будет более громоздким.
Absolute Layout
Абсолютная разметка не очень удобна, поскольку нужно указывать координаты элементов явно. Может, когда-то она вам пригодится, а сейчас лишь приведу при- мер с двумя кнопками: OK и Отмена (листинг 5.7), расположение которых задает- ся явно.
Листинг 5.7. Пример абсолютной разметки


102
Часть II. Базовое программирование для Android
Рис. 5.13. Эмулятор с загруженным приложением
Рис. 5.14. Утилита Hierarchy Viewer

Глава 5. Разработка интерфейса пользователя
103
(рис. 5.14) щелкните по ссылке , а затем нажмите кнопку
Load View Hierarchy
3. Немного подождите и вы увидите иерархию интерфейса пользователя запущен- ного приложения (рис. 5.15). Изменить масштаб иерархии можно с помощью колесика мыши.
Рис. 5.15. Иерархия интерфейса пользователя
5.2. Основные виджеты графического интерфейса
Виджеты — это элементы графического интерфейса. Ранее мы уже познакомились с двумя виджетами: текстовым полем и кнопкой. Сейчас мы наше знакомство с виджетами продолжим.
Прежде чем приступить, создайте новый проект с именем
Test5
, деятельность этого проекта назовем
Test5Activity
, а пакет: com.samples.test5
— так вам будет понят- нее, откуда взялись некоторые идентификаторы.

104
Часть II. Базовое программирование для Android
5.2.1. Текстовые поля
В Android вы можете использовать два текстовых поля:
TextView и
EditText
. Первое служит для отображения текста без возможности его редактирования, а второе — это классическое текстовое поле с возможностью ввода и редактирования текста.
Несмотря на свою простоту, виджет
TextView довольно часто применяется в Android-программах для вывода инструкций по работе с программой и другого текста.
В файле разметки значение
TextView можно установить так: android:text="Text";
В Java-коде значение виджета устанавливается так:
TextView text = (TextView)findViewById(R.id.textView1); text.setText("Sample text");
Совсем другое дело, если вы планируете создать приложения с многоязыковой поддержкой пользовательского интерфейса. Тогда непосредственно в файле раз- метки значение (текстовую строку) указывать не нужно. Вместо этого создается ссылка на текстовый XML-ресурс: android:text="@string/str_value"
Здесь str_value
— это имя строкового ресурса, описанного в файле strings.xml
В Java-коде установить имя ресурса можно тем же методом setText()
:
TextView text = (TextView)findViewById(R.id.textView1); text.setText(R.string.str_value);
У элемента
TextView есть много методов и свойств. Мы рассмотрим только основ- ные свойства, относящиеся к отображению текста.
Размер шрифта задается свойством android:textSize в пикселах (
px
), независимых от плотности пикселах (
dp
), независимых от масштабирования пикселах (
sp
), пунк- тах (
pt
), дюймах (
in
) и миллиметрах (
mm
): android:textSize="14pt";
Стиль текста задается свойством android:textStyle
: normal
— обычное начертание символов; bold
— полужирное начертание символов; italic
— курсив.
Например: android:text
Цвет шрифта задается в свойстве android:textColor указанием его значений в шестнадцатеричной кодировке в формате #RGB или #ARGB. Во втором случае значение A — это прозрачность. Если A = 0, то прозрачность 100 % (элемент прак- тически не будет виден).

Глава 5. Разработка интерфейса пользователя
105
Теперь немного практики. Создайте новый проект. По умолчанию будет создан проект, выводящий строку «
Hello World!
» с помощью
TextView
— как раз то, что нам и нужно.
П
ОЛОСЫ ПРОКРУТКИ
По умолчанию, если текст не помещается в виджете TextView, появляются полосы прокрутки. Другими словами, вам ничего не нужно делать для того, чтобы они появи- лись. Но если есть желание отображать полосы прокрутки, даже когда они не нужны, вы можете использовать виджеты ScrollView (вертикальная полоса прокрутки) и
HorizontalScrollView
(горизонтальная полоса прокрутки). Прочитать об этих видже- тах можно в руководстве по Android:
• http://developer.android.com/reference/android/widget/ScrollView.html
• http://developer.android.com/reference/android/widget/HorizontalScrollView.html
Перейдите к файлу разметки проекта — res/layout/activity_main.xml
. Попробуем изме- нить свойства
TextView
. Если вы забыли, как называется то или иное свойство, —
Eclipse его вам подскажет. Наберите: android:
и немного подождите — откроется выпадающий список, из которого нужно будет выбрать искомое свойство
(рис. 5.16). Как видите, Eclipse помогает писать не только Java-код, но и файлы разметки.
Рис. 5.16. Подсказка Eclipse при создании файла разметки
Установим свойства textSize и textStyle
, а также присвоим имя нашему текстово- му полю (
txt1
), чтобы к нему можно было обратиться из Java-кода (листинг 5.8 и рис. 5.17).
Листинг 5.8. Файл activity_main.xml, установка атрибутов TextView

>

106
Часть II. Базовое программирование для Android
/>


Рис. 5.17. Изменение размера и стиля шрифта
Теперь попробуем усложнить задачу и изменить текст нашего виджета из Java- кода. Для этого откройте файл, содержащий Java-код нашего приложения: src/<название пакета>/<название_проекта>Activity.java
. В нашем случае этот файл назы- вается src/com.samples.test5/Test5Activity.java
. На рис. 5.18 показано содержимое этого файла по умолчанию, а также область Package Explorer, объясняющая, как «доб- раться» до этого файла.

Глава 5. Разработка интерфейса пользователя
107
Рис. 5.18. Файл Test5Activity.java
Измените Java-файл так, чтобы он выглядел, как показано в листинге 5.9. Чтобы работать с виджетом
TextView
, нужно импортировать пакет android.widget.
TextView
. Самые важные строки выделены полужирным шрифтом, а лишние — удалены для компактности кода.
Листинг 5.9. Файл Test5Activity.java
/* первая строка зависит от названия вашего пакета, у вас будет другой */ package com.samples.test5; import android.support.v7.app.ActionBarActivity; import android.os.Bundle; import android.widget.TextView;
/* название класса (Test5Activity) зависит от параметров, указанных при создании проекта */ public class Test5Activity extends ActionBarActivity {

108
Часть II. Базовое программирование для Android
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test5);
TextView txt1 = (TextView)findViewById(R.id.txt1); txt1.setText("Hi!");
}
}
Теперь запустите приложение. В качестве значения текстового поля установлена строка "Hi!"
(рис. 5.19).
Рис. 5.19. Результат работы нашей программы
Текстовое поле
EditText
, как уже было отмечено, позволяет вводить и редактиро- вать текст. Основной метод этого поля — getText()
, позволяющий получить вве- денный пользователем текст. Значение, возвращаемое методом getText()
, имеет

Глава 5. Разработка интерфейса пользователя
109 тип
Editable
. По сути,
Editable
— это надстройка над
String
, но, в отличие от него, значение типа
Editable может быть изменено в процессе выполнения программы
(
String является неизменяемым типом, и при изменении типа
String попросту соз- дается другой экземпляр
String
, содержащий новое значение).
Кроме метода getText()
вам может понадобиться метод selectAll()
, выделяющий весь текст в окне
EditText
. Если весь текст выделять не нужно, можно использовать метод setSelection()
: setSelection(int start, int stop)
Этот метод выделяет участок текста, начиная с позиции start до позиции stop
Установить тип начертания шрифта можно с помощью метода setTypeface
— на- пример: txt1.setTypeface(null, Typeface.NORMAL);
Вместо
NORMAL
можно указать
BOLD
и/или
ITALIC
Для добавления поля
EditText в разметку окна нужно поместить в файл разметки следующий код:

Далее мы научимся работать с этим полем — займемся получением и установкой текста поля. А пока ограничимся только тем, что добавим поле в файл разметки.
Как выглядит это поле, вы уже видели на рис. 5.19.
5.2.2. Кнопки
Кнопки — очень важный элемент пользовательского интерфейса. К кнопкам отно- сятся не только непосредственно сами кнопки, но и переключатели (независимые и зависимые). Для определения кнопок имеется пять классов:
Button
;
CheckButton
;
ToggleButton
;
RadioButton
;
ImageButton
Классы
CheckButton
,
ToggleButton и
RadioButton являются потомками класса
CompoundButton
, который, в свою очередь, является потомком класса
Button
. А вот класс
ImageButton является потомком класса
ImageView
, поэтому
ImageButton пред- ставляет собой более изображение, нежели кнопку — в прямом понимании этого слова. Имеется также кнопка
SmallButton
, которая выглядит практически так же, как и
Button
, только ее размеры более компактные. Кнопки
Button и
SmallButton

110
Часть II. Базовое программирование для Android отличаются только атрибутом style
. Для обычной кнопки он не указывается, а для
SmallButton выглядит так:
Button
— обычная кнопка
Начнем с обычной кнопки и продемонстрируем создание относительно простого приложения. Java-кода в этом приложении будет чуть больше, чем обычно, поэто- му читателям, не знакомым с Java, нужно быть внимательными, чтобы не допус- тить ошибку.
Добавьте в наш проект, демонстрирующий изменение значения текстового поля с помощью Java-кода, одну кнопку. Теперь изменение значения текстового поля будет происходить не при запуске приложения, а при нажатии кнопки (рис. 5.20).
Рис. 5.20. Разметка проекта с текстовым полем и кнопкой
XML-разметка этого проекта представлена в листинге 5.10.
Листинг 5.10. Файл разметки проекта с текстовым полем и кнопкой

>

Глава 5. Разработка интерфейса пользователя
111 android:layout_width="fill_parent" android:layout_height="wrap_content" android:textSize="20pt" android:text android:text="@string/hello_world"
/>


Обратите внимание на идентификаторы текстового поля и кнопки. Текстовое поле называется txt1
, а кнопка — button1
. Этими идентификаторами мы воспользуемся в Java-коде. Также не забудьте указать в файле strings.xml константу press_me со зна- чением "Нажми меня"
Кстати, приятно, когда Eclipse пишет код за вас — автодополнение кода очень удачно реализовано в этой IDE. Java-код нашего приложения приведен в листинге 5.11.
Листинг 5.11. Java-код второго проекта
/* первая строка зависит от названия вашего пакета, у вас будет другой */ package com.samples.test5; import android.support.v7.app.ActionBarActivity; import android.os.Bundle; import android.widget.TextView; import android.widget.Button; import android.view.View;

/* название класса (Test5Activity) зависит от параметров, указанных при создании проекта */ public class Test5Activity extends ActionBarActivity { private
TextView txt1;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test5);

112
Часть II. Базовое программирование для Android
/* находим текстовое поле */ txt1 = (TextView)findViewById(R.id.txt1);
/* находим кнопку */ final Button button1 = (Button)findViewById(R.id.button1); button1.setOnClickListener(new View.OnClickListener() {

public void onClick(View v)
{
//
TODO
Auto-generated method stub txt1.setText("Hi!");

}
});
}
}
Как обычно, самые важные моменты, на которые нужно обратить внимание, выде- лены полужирным шрифтом. Сначала мы объявляем переменную txt1
— для тек- стового поля. Затем находим текстовое поле и кнопку. После этого с помощью метода setOnClickListener()
устанавливаем обработчик события — в нашем случае нажатия кнопки. Обработчик события очень прост: мы устанавливаем новое значе- ние текстового поля txt1
Теперь запустите приложение. Сначала будет выведена строка Hello World!
(рис. 5.21, а), а после нажатия кнопки строка будет изменена на Hi! (рис. 5.21, б).
Думаю, как установить обработчик нажатия кнопки, понятно. Однако код получил- ся довольно громоздкий. Скажем, когда у вас одна или две кнопки, то такой код — это не проблема. А вот когда у вас 5 кнопок (или больше), то очень легко запутать- ся — уж больно много скобок. Хотя Eclipse делает все возможное, чтобы вам по- мочь, есть один способ уменьшить код и существенно упростить его для воспри- ятия.
Представим, что вы в файле разметки объявили пять кнопок с именами от button1
до button5
. Сначала находим кнопки: final Button button1 = (Button)findViewById(R.id.button1); final Button button2 = (Button)findViewById(R.id.button2); final Button button5 = (Button)findViewById(R.id.button5);
Потом устанавливаем один обработчик для всех кнопок: button1.setOnClickListener(this); button2.setOnClickListener(this); button5.setOnClickListener(this);
Затем анализируем, какая кнопка была нажата, и выполняем соответствующее дей- ствие:

Глава 5. Разработка интерфейса пользователя
113
@Override public void onClick(View v) { switch (v.getId()) { case R.id.button1: txt1.setText("Button 1"); break; case R.id.button2: txt1.setText("Button 2"); break; case R.id.button3: txt1.setText("Button 3"); break; case R.id.button4: txt1.setText("Button 4"); break; case R.id.button5: txt1.setText("Button 5"); break;
}
}
Есть еще один способ описания обработчика кнопки. В файле разметки нужно установить свойство android:onClick
, содержащее имя обработчика, который будет вызван. Например:

114
Часть II. Базовое программирование для Android
RadioButton
— зависимые переключатели
Зависимые переключатели (виджеты класса
RadioButton
) используются внутри кон- тейнера
RadioGroup
— группы зависимых переключателей. Зависимый переключа- тель позволяет выбрать только одну из опций в одной из групп переключателей.
В каждой из групп может быть активным только один переключатель.
Вы в основном будете пользоваться тремя методами: toggle()
— инвертирует состояние зависимого переключателя; isChecked()
— возвращает значение зависимого переключателя (
true
— ак- тивен); setChecked()
— изменяет значение переключателя в зависимости от переданного параметра.
Для демонстрации работы с зависимыми переключателями добавьте в наш проект с кнопкой и текстовым полем два зависимых переключателя с именами r1
и r2
. При нажатии кнопки значение текстового поля будет изменено в зависимости от вы- бранного переключателя. Если ни один из переключателей не выбран, значение
TextView изменено не будет. Разметка проекта приведена в листинге 5.12.
Листинг 5.12. Файл разметки проекта (зависимые переключатели)






/>

Глава 5. Разработка интерфейса пользователя
115


Определением, какой переключатель активен, занимается обработчик нажатия кнопки. Для этого он использует метод isChecked()
— листинг 5.13.
Листинг 5.13. Java-код проекта (зависимые переключатели) package com.samples.test5; import android.support.v7.app.ActionBarActivity; import android.os.Bundle; import android.widget.TextView; import android.widget.Button; import android.widget.RadioButton; import android.view.View; public class Test5Activity extends ActionBarActivity {
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test5); final TextView txt1 = (TextView)findViewById(R.id.txt1); final RadioButton r1 = (RadioButton)findViewById(R.id.r1); final RadioButton r2 = (RadioButton)findViewById(R.id.r2); final Button button1 = (Button)findViewById(R.id.button1); button1.setOnClickListener(new View.OnClickListener() {

public void onClick(View v)
{
//
TODO
Auto-generated method stub if
(r1.isChecked()) txt1.setText("Value
1"); if
(r2.isChecked()) txt1.setText("Value
2");

}
});
}
}
Как видите, все довольно просто. Готовое приложение показано на рис. 5.22.

116
Часть II. Базовое программирование для Android
Рис. 5.22. Демонстрация использования зависимых переключателей
CheckBox
— независимые переключатели
Переключатели
CheckBox не привязываются к какому-либо контейнеру (вроде
RadioGroup
), значение независимого переключателя не зависит от состояния других переключателей, поэтому такие переключатели и называются независимыми.
Для работы с
CheckBox вы можете использовать те же методы (
isChecked()
, toggle()
, setChecked()
), что и в случае с
RadioButton
. В файле разметки независи- мые переключатели определяются так:

Найти
Checkbox в Java-коде можно так: final CheckBox check = (CheckBox)findViewById(R.id.checkbox);

Глава 5. Разработка интерфейса пользователя
117
Далее можно проверить, включен ли переключатель: if (check.isChecked()) txt1.setText("OK");
ToggleButton
— кнопка включено/выключено
Кнопка
ToggleButton может находиться в одном из положений: включено или вы- ключено. Когда кнопка нажата, горит зеленый индикатор, как бы «встроенный» в кнопку, а также видно, что кнопка немного вдавлена.
По большому счету от
ToggleButton можно было отказаться и использовать обыч- ный виджет
CheckBox
, однако кнопка
ToggleButton выглядит более привлекательно и больше подходит для включения/выключения режимов программы, чем пере- ключатель
CheckBox
У кнопки есть два основных свойства: android:textOff и android:textOn
. Первое устанавливает текст кнопки, когда она выключена, а второе — когда включена.
В программном коде этим свойствам соответствуют методы setTextOff()
и setTextOn()
С помощью метода setChecked(boolean checked)
вы можете программно изме- нить состояние кнопки. При изменении состояния генерируется событие onCheckedChanged()
Добавьте в наш проект кнопку
ToggleButton и удалите все, что нам не нужно. Пусть в проекте останутся только текстовое поле
TextView
, кнопка
Button
(она нам еще пригодится) и новая кнопка
ToggleButton
. Разметка проекта представлена в листин- ге 5.14.
Листинг 5.14. Разметка проекта (демонстрация использования ToggleButton)

>
/>

118
Часть II. Базовое программирование для Android android:layout_height="wrap_content">




При нажатии кнопки
ToggleButton будет изменяться значение текстового поля в зависимости от состояния кнопки. Такой эффект достигается благодаря обработ- чику события
OnCheckedChange
. В коде программы есть еще и обработчик нажатия обычной кнопки — он просто устанавливает значение текстового поля. Вы можете от него отказаться, как и от самой кнопки
Button
. Код Java представлен в листин- ге 5.15, а результат показан на рис. 5.23 — кнопка
ToggleButton нажата и текст за- менен на Turbo mode on.
Рис. 5.23.
ToggleButton в действии

Глава 5. Разработка интерфейса пользователя
119
Листинг 5.15. Java-код проекта (использование ToggleButton) package com.samples.test5; import android.support.v7.app.ActionBarActivity; import android.os.Bundle; import android.widget.TextView; import android.widget.Button; import android.widget.CompoundButton; import android.widget.ToggleButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.view.View; public class Test5Activity extends ActionBarActivity {
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test5); final TextView txt1 = (TextView)findViewById(R.id.txt1); final Button button1 = (Button)findViewById(R.id.button1); final ToggleButton tButton = (ToggleButton)findViewById(R.id.tb1); tButton.setOnCheckedChangeListener(new OnCheckedChangeListener() {
public void onCheckedChanged(
CompoundButton buttonView, boolean isChecked) {
// TODO Auto-generated method stub
if (isChecked) txt1.setText("Turbo mode on"); else txt1.setText("Turbo mode off");

}
}); button1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {

// TODO Auto-generated method stub
txt1.setText("Default mode");

}
});
}
}

120
Часть II. Базовое программирование для Android
ImageButton
— кнопка с изображением
Виджет
ImageButton
— нечто среднее между изображением и кнопкой. Вместо тек- ста на эту кнопку будет выведено изображение, что позволяет создавать более при- влекательные кнопки.
Установить изображение кнопки можно или атрибутом android:src элемента

Каталог: images -> files
files -> Программа духовно-нравственного развития и воспитания обучающихся на уровне среднего общего образования
files -> Реклама на сайтерегистрация
files -> Вид: детский сад. Юридический адрес
files -> Рабочая программа по предмету по выбору«Общее фортепиано» Преподавателя Клюевой Т. А принята на заседании
files -> Рабочая программа по учебной дисциплине «Информатика» для детей 5-7 лет
files -> Использование информационных технологий в доу


Поделитесь с Вашими друзьями:
1   2   3   4   5   6   7   8


База данных защищена авторским правом ©nethash.ru 2019
обратиться к администрации

войти | регистрация
    Главная страница


загрузить материал