Недавно заинтересовала меня платформа Android. Как-то много говорят о нем в последнее время, да и вообще хотелось узнать, такая же ли там ужасная Java, как в мидлетах. Так что потратила я некоторое время на копание в нем, написала простое приложение, и сейчас вот буду делиться опытом.
UPDATE
Серия статей по игре Life обновлена 03.11.2010. Исправлены ошибки и проведена адаптация под Android версии 2.2. Всем спасибо за замечания и дополнения!Постановка задачи
Первым нашим приложением для Android будет реализация всем известной игры Life. Местом дейтвия будет прямоугольное клеточное поле, размеры которого запрашиваются у пользователя. Также у пользователя запрашивается начальное количество клеток. Первое поколение расставляется по карте случайным образом. Последующие поколения получаются по следующим правилам:
- Если у живой клетки меньше двух или больше трёх соседей, то она погибает.
- Если у пустой клетки ровно три соседки, она оживает.
Все входные параметры должны проверяться на правильность: столбцов должно быть не меньше 5 и не больше 25, строк должно быть не меньше 5 и не больше 35, начальное количество клеток должно быть не больше, чем ячеек на поле. Для реализации поля будет использован класс GridView.
Для разработки была использована среда
Eclipse и
Android plugin для неё.
Статья будет из четырех частей:
Итак, начнём.
В этой части
Мы создадим проект, рассмотрим его структуру и напишем простое приложение, состоящее из одной формы. На форме будет интерфейс для ввода данных и кнопка Run.
Создание и обзор проекта
На установке Android SDK и плагина для Eclipse останавливаться не будем, т.к. это достаточно подробно описано в официальном мануале. Создаем в Eclipse новый
Android Project:
После нажатия на кнопку
Finish создастся новый проект с такой структурой файлов:
Рассмотрим эту структуру внимательнее.
/res/drawable-dpi
Сюда помещаются все графические файлы, используемые в приложении, для разных разрешений экрана. На данный момент там есть только файл icon.png - главная иконка приложения.
/res/layout
В эту папку помещаются файлы, в которых в формате XML описывается внешний вид форм, расположение контролов и т.д. (как dfm-ки в Дельфи). Плагин даже создал разметку для нашей единственной формы и назвал её main.xml. Позже мы рассмотрим ее подробнее.
/res/values
В этой папке хранятся общие константы для всего приложения, как то: текст, используемый элементами управления, цвета, стили и т.д.. Например, если мы хотим вывести "Hello World" в TextView, можно это сделать явно в разметке, как мы всю жизнь делали в тех же dfm-ках или aspx; либо создать в
strings.xml
константу
hello
со значением "Hello World", после чего пойти обратно в разметку и в атрибутах этого TextView прописать
android:text="@string/hello"
.
/gen/R.java
Это такой специальный сгенерированный класс, посредством которого осуществляется доступ к ресурсам приложения (т.е. ко всему тому, что есть в папке
res
). Например,
R.string.hello
возвращает константу с именем
hello
из
strings.xml
.
StartActivity.java
Это нам плагин сгенерировал класс для главной (и пока что единственной) формы приложения. Там пока содержится единственный обработчик
onCreate
, и написано там только
setContentView(R.layout.main);
. С помощью этой строчки к данной форме привязывается разметка, описанная в файле
/res/layout/main.xml
AndroidManifest.xml
В этом файле перечисляются общие свойства проекта (версия, package и прочее), а также все формы (Activities), входящие в проект.
Разметка формы (Layout)
Элементы управления в Android называются
Views и наследуются от класса
View
или
ViewGroup
. Класс
ViewGroup
также унаследован от
View
, но его отличие в том, что в него могут быть вложены другие
View
или
ViewGroup
.
Плагин создал простейшую разметку для нашей единственной формы (
main.xml
):
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
</LinearLayout>
Вначале задаётся
Layout, т.е. правило, согласно которому элементы управления следуют друг за другом.
LinearLayout
значит, что они идут друг за другом сверху вниз (
android:orientation="vertical"
). Бывают и другие Layout-ы:
TableLayout
, с помощью которого можно выстроить контролы в таблицу;
FrameLayout
, который ставит контролы один на другой; и т.д.
Мы воспользуемся
TableLayout
Сделаем вот такую разметку:
main.xml
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:stretchColumns="1"
android:padding="10dip"
>
<TableRow android:paddingBottom="5dip">
<TextView
android:text="@string/columns_title"
android:paddingRight="10dip"
android:gravity="right"
android:textStyle="bold"
/>
<EditText
android:id="@+id/columns_count"
android:text="25"
android:inputType="number"
/>
</TableRow>
<TableRow android:paddingBottom="5dip">
<TextView
android:text="@string/rows_title"
android:paddingRight="10dip"
android:gravity="right"
android:textStyle="bold"
/>
<EditText
android:id="@+id/rows_count"
android:text="35"
android:inputType="number"
/>
</TableRow>
<TableRow android:paddingBottom="5dip">
<TextView
android:text="@string/cells_title"
android:paddingRight="10dip"
android:gravity="right"
android:textStyle="bold"
/>
<EditText
android:id="@+id/cells_count"
android:text="100"
android:inputType="number"
/>
</TableRow>
<TableRow>
<Button
android:id="@+id/run"
android:text="@string/run_title"
android:textStyle="bold"
android:layout_span="2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</TableRow>
</TableLayout>
В файл
res/values/strings.xml
при этом нужно добавить следующие строки:
strings.xml
<string name="run_title">Run!</string>
<string name="columns_title">Columns:</string>
<string name="rows_title">Rows:</string>
<string name="cells_title">Cells:</string>
Форма при этом будет выглядеть так:
Рассмотрим некоторые атрибуты, использованные в разметке
android:id
Идентификатор элемента. Если он указан, то в дальнейшем его можно найти на форме с помощью метода
findViewById(id)
. Для контролов, которых мы не планируем в дальнейшем трогать (например, для заголовков), можно это свойство и вовсе не указывать. Идентификаторы можно складывать в файл
ids.xml
, но вместо этого обычно применяется синтаксис
@+id/View1
. Это означает, что идентификатор
View1
добавляется в константы прямо на ходу. В
R.java
соответствующие поля также добавляются автоматически.
android:layout_width и android:layout_heigth
Свойства
layout_width
и
layout_heigth
обозначают, какую часть родительского контрола будет занимать данный элемент управления: всю (
fill_parent
или
match_parent
, начиная с 2.2) или ровно столько, сколько требуется (
wrap_content
). Можно также задавать численные значения.
android:inputType
Это атрибут
EditText
. С его помощью можно устанавливать формат вводимого значения. Есть ряд предопределенных форматов (
date
,
phone
, etc). Значение
number
значит, что в это поле можно вводить только целые положительные числа.
android:gravity, android:layout_gravity
Устанавливает выравнивание в данном элементе управления. Отличие в том, что
gravity
задает выравнивание дочерних контролов, а
layout_gravity
задает выравнивание самого контрола.
Заключение
Итак, мы создали проект для Android, рассмотрели его структуру, составили разметку для нашей единственной формы.
Исходники примера