UPDATE
Серия статей по игре Life обновлена 03.11.2010. Исправлены ошибки и проведена адаптация под Android версии 2.2. Всем спасибо за замечания и дополнения!Постановка задачи
Первым нашим приложением для Android будет реализация всем известной игры Life. Местом дейтвия будет прямоугольное клеточное поле, размеры которого запрашиваются у пользователя. Также у пользователя запрашивается начальное количество клеток. Первое поколение расставляется по карте случайным образом. Последующие поколения получаются по следующим правилам:- Если у живой клетки меньше двух или больше трёх соседей, то она погибает.
- Если у пустой клетки ровно три соседки, она оживает.
Для разработки была использована среда Eclipse и Android plugin для неё.
Статья будет из четырех частей:
- Часть 1 — Простое приложение для Android
- Часть 2 — Переходы между формами
- Часть 3 — Использование диалогов
- Часть 4 — Использование GridView
В этой части
Мы создадим проект, рассмотрим его структуру и напишем простое приложение, состоящее из одной формы. На форме будет интерфейс для ввода данных и кнопка 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>
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, рассмотрели его структуру, составили разметку для нашей единственной формы.Исходники примера
Интересно, как вы сделали расцветку кода XML для публикования на blogspot.com?
ОтветитьУдалитьЯ написала свой подсветчик синтаксиса, и он умеет раскрашивать код не только цветами (<span style="color=...">), но и классами (<span class="...">). Ну а соответствующие классы я добавила прямо в шаблон блога. Если Firebug-ом посмотреть на css-ку моего блога, можно легко их там увидеть.
ОтветитьУдалитьСпасибо огромное.
ОтветитьУдалитьЯ тоже заинтересовался этой платформной. Правдя я только начинающий программист :)
Вообще-то я тестер. И вот, что я Вам скажу:
Здесь немного перепутаны значения полей: ColumnsEditor для Rows.
Просто так будет легче остальным пробовать начинать :)))
То же самое в папочке res в проекте Life для скачивания.
Еще раз Огромное спасибо :)
http://iamandroid.ru/ - линка с которой я узнал о Вас :)
4i4a
Ой, и вправду. Спасибо за замечания, исправила.
ОтветитьУдалитьнебольшая неточность:
ОтветитьУдалитьСтатья будет из трёх частей:
* Часть 1
* Часть 2
* Часть 3
* Часть 4
Отличная статья. Пытаюсь освоить новую платформу. Но хочу заметить, что программировать интерфейс пользователя на Visual Studio для Windows Mobile гораздо легче.
ОтветитьУдалитьСпасибо за мануал. Очень заинтересовала платформа, начинаю ковырять. И вот не могу понять в чем проблема: в main.xml все теги закрыты и соответствуют друг другу, но выползает ошибка - "Element type "TableLayout" must be followed by either attribute specifications, ">" or "/>"."(Eclipse + Android SDK)
ОтветитьУдалитьУ меня та же самая фигня. Долго ковырялся, пытался понять, в чем проблема. В итоге просто перебил текст вручную. Все запахало :)
ОтветитьУдалитьвсе проблема в символах перевода строк(пробелы. хз). Тупо копируем и вручную все заново переводим на новые строки..
ОтветитьУдалитьПодскажите - а есть ли среды разработки, полностью работающие на телефоне под управлением андроида? :) Аппарат так и просит, чтобы вся работа делалась непосредственно на нём :)
ОтветитьУдалить2 BOJIKOJIAK
ОтветитьУдалитьХотите прямо на телефоне софт писать? Однако сурово. Сильно сомневаюсь, что такое бывает.
Не знаю как на андроиде, а вот для простого мобильника первые приложения делал на самом мобильнике :)
ОтветитьУдалить2 Анонимный №3:
ОтветитьУдалитьНеужели IDE на телефоне запускали? И через T9 код писали?
По поводу разработки непосредственно на девайсе - существует Android Scripting Environment (ASE) - позволяет писать скрипты на Lua, Perl'e, Python'e, Tcl'e. Так же реализована поддержка shell (BeanShell) и есть подержка jRuby.
ОтветитьУдалитьDarja, u vas v razmetke stranicy "sledushee" i "predydushee" naoborot)
ОтветитьУдалитьделаю всё как написано, а он выдает ошибку Element type "TableLayout" must be followed by either attribute specifications, ">" or "/>" и error: Error parsing XML: not well-formed (invalid token).
ОтветитьУдалитьПри этом указывает на строчку android:layout_width="fill_parent".
помогите пожалуйста разобраться.
наткнулся на интересную бету DroidDraw. Умеет пока немного, но все же проще, да и мопнятне ифейс рисовать в ней, чем руками в xml
ОтветитьУдалитьСсылки перехода следующее и предыдущие перепутаны. )) Блог замечательный.)
ОтветитьУдалитьНачал пробовать свои силы в android 2.2. Так вот атрибут "android:numeric" считается там устаревшим и рекомендуется использовать android:inputType
ОтветитьУдалитьЗЫ: блог замечательный, написано аккуратно, по полочкам. Спасибо за Ваши труды.
Ваша правда, спасибо, исправилась.
ОтветитьУдалитьКстати IDE уже не предлагает в автоподстановке android:layout_span
ОтветитьУдалитьно предлагает android:layout_weight, который дает тот-же самый эффект.
Добрый день!
ОтветитьУдалитьВозможно где-то писалось, но не нашел.
Как устанавливается свойство, чтобы при изменении ориентации телефона ориентация приложения не менялась?
Спасибо, нашел и разобрался.
ОтветитьУдалитьhttp://www.goodroid.ru/faq/programming-for-android-os/disable-screen-orientation-change.html
http://russia-android.ucoz.ru/load январская книжка 2011 г. по теме.
ОтветитьУдалитьскопировал ваш код, получил ошибку:
ОтветитьУдалитьerror: Invalid start tag TableLayout
в файлt main.xml
Здравстуйте, Дарья!
ОтветитьУдалитьНедавно видел пару Ваши статей на androidfan.ru
Black Diver комментирует...
ОтветитьУдалитьКстати IDE уже не предлагает в автоподстановке android:layout_span
но предлагает android:layout_weight, который дает тот-же самый эффект.
Свойство android:layout_weight работает аналогично свойству weigth из класса библиотеки Swing (Java SE): GridBagConstraints.
Отличный пост!
ОтветитьУдалитьСпасибо за пост. Все доступно и понятно.
ОтветитьУдалитьМне кажется на Windows xp легче программировать чем для android
ОтветитьУдалитьЭтот комментарий был удален автором.
ОтветитьУдалитьПытаюсь освоить Android. Пишу программу для отправки СМС. Вопрос: как прочитать данные из активного окна при приеме СМС?
ОтветитьУдалитьТ.Е. имеем активное окно в котором набираем номер телефона и текст и нажимаем кнопку отправить. Далее перехватываем ответную СМС. Событие перехвата написано в другом классе. В нем надо принять СМС и сравнить с номером телефона при отправке. Далее текст принимаемой СМС вывести в EditText активного окна.
"Элементы управления в Android называются Views и наследуются от класса View или ViewGroup. Класс ViewGroup также унаследован от View, но его отличие в том, что в него могут быть вложены другие View или ViewGroup."
ОтветитьУдалитьЭтой фразой вы взорвали мой императивный мозг...