Создание приложения в стиле Android

Часто, интерфейс даже очень популярных Android-приложений спроектирован кое-как и складывается впечатление, что большинство разработчиков даже не слышало о User Interface Guidelines. Но следование рекомендациям не очень сложно, а иногда даже позволяет экономить время на разработку. Для того, чтобы показать, что это действительно так, я предлагаю пройтись по нескольким ключевым элементам проектирования интерфейса приложения на примере слегка продвинутого «Hello World».
Статья расчитана на начинающих Android-разработчиков. Исходный код можно скачать по ссылке в конце, а пояснения будут касаться:
  • Создания всплывающего меню
  • Проектирования окна настроек
  • Работы с Nine-patch graphics


Предварительная подготовка


1. Создаем приложение AdvancedHelloWorld. Для программ, которые не используют спецефическую функциональность определенной версии ОС, я предпочитаю ставить BuildTarget — Android 1.6, а Min SDK Version — 3. В этом случае будет работать разделение ресурсов по плотности экрана (на hdpi, mdpi, ldpi), но и пользователи Android 1.5 не останутся в стороне.
image
2. В res/layout/main.xml делаем одну кнопку «Say hello».
3. С помощью замечательного проекта Android Asset Studio делаем приятную иконку.
4. В качестве обработчика щелчка по кнопке пишем код, который покажет Toast-сообщение с фразой «Hello World».

Об Android Asset Studio

Open source онлайн проект, ценность которого сложно переоценить. Позволяет быстро создавать иконки приложения (launcher icons), иконки меню, закладок и оповещения. Для работы он просит Chrome 6, в других браузерах некоторые элементы не работают. Ссылка в конце статьи.

Замечание по поводу ресурсов

На мой взгляд, наиболее рациональный выбор — это использование отдельного набора графики для hdpi-устройств и отдельного — для всех остальных, в разрешении, адаптированном под mdpi. Да, мы не используем возможность адаптации под ldpi, но этих устройств сравнительно немного и можно оставить полную адаптацию на «закуску», когда все графическое оформление уже устоялось. В любом случае, поскольку мы задекларировали поддержку Android 1.5, в папке drawable должны быть все испльзуемые графические элементы. Остальное — по желанию.

Всплывающее меню



Меню описываются, как не сложно догадаться, в xml файлах. Сделаем один такой файл для нашего главного окна: res\menu\main_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/menu_preferences"
android:icon="@drawable/ic_menu_preferences"
android:title="@string/menu_preferences" />
<item android:id="@+id/menu_theme"
android:icon="@drawable/ic_menu_theme"
android:title="@string/menu_theme" />
<item android:id="@+id/menu_close"
android:icon="@drawable/ic_menu_close_clear_cancel"
android:title="@string/menu_close" />
</menu>



Два момента:
Если количество пунктов меню больше 6, 6-й и следующие элементы объединяются в дополнительное меню. Пример можно посмотреть в стандартном браузере.
Меню может быть вложенным, но не более одного уровня. Для описания вложенного меню добавляется тег menu в качестве дочернего к тому элементу, который будет «разворачиваться».


При создании меню первым делом стоит поискать иконки в стандартном наборе. Все они есть в установленном SDK — android-sdk-windows\platforms\android-1.6\data\res\drawable\ic_menu_*.png
Иконку настройки и выхода подобрать не сложно, но, для иллюстрации, я добавил пункт меню «тема», который будет переключать фон с черного на белый и назад. Даже обладая совсем базовыми навыками в компьютерной графике, несложно нарисовать шаблон и для этого пункта. Например:
image
С помощью все того же Android Asset Studio получится вполне неплохая иконка:
image

Фактическое создание пунктов меню происходит в onCreateOptionsMenu:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
return true;
}


Обработка нажатий — в onOptionsItemSelected:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_preferences:
...
default:
return super.onOptionsItemSelected(item);
}
}


Проектирование окна настроек


И снова, основная работа в xml. В res\xml создем settings.xml:

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="@string/settings_general">
<CheckBoxPreference
android:key="center_message"
android:title="@string/center_message"
android:summary="@string/center_message_summary"
android:persistent="true"
android:defaultValue="true"/>
<EditTextPreference
android:key="text_message"
android:title="@string/text_message"
android:summary="@string/text_message_summary"
android:defaultValue="@string/hello_world"
android:persistent="true"/>
</PreferenceCategory>
</PreferenceScreen>


Набор поддерживаемых настроек не очень широкий, но основные потребности он покроет. Устанавливая флаг «persistent» нам даже не придется кодировать сохранение/загрузку. Достаточно прочитать нужное значение из SharedPreferences:

SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
boolean bCenter = settings.getBoolean("center_message", true);


В качестве дополнительных приятных моментов можно отметить зависимости (android:dependency), которые позволяют «включать» определенные пункты только в случае отмеченного «ведущего» элемента, а также простую работу с вложенными наборами, которые в приложении выглядят как отдельные окна.
Для окна настроек создается свой класс-наследник PreferenceActivity, в конструкторе которого и считывается наш xml-прототип:
addPreferencesFromResource(R.xml.settings);

PreferenceActivity плохо поддается стилизации. Можно, конечно, для соответствующего тэга в AndroidManifest.xml добавить android:theme="@android:style/Theme.Light", но для вложенных настроек получится каша. Обсуждение этой проблемы на Stackoverflow сводится к мысли, что, в общем случае, лучше оставлять все как есть, на черном фоне.

Работа с Nine-patch graphics



Nine-patch — это стандартный метод, позволяющий сделать графику в Android-приложении независимой от разрешения и размера экрана. По сути, это обычное изображение в формате png с однописксельной служебной рамкой. Для правильной работы с этой рамкой в состав SDK входит специальная утилита draw9patch. Черной линией толщиной в 1 пиксель сверху и слева отмечается область, которая будет дублироваться при увеличении изображения. Линии справа и снизу определяют «рабочую область». Для обычной кнопки, например, это место для текста.
На словах достаточно трудно объяснить возможности 9patch, поэтому лучше экспериментировать и смотреть, тем более, что при редактировании областей 9patch можно сразу видеть результат в окне предпросмотра. Вот как выглядит фон стандартной кнопки в редакторе:
image
Для тренировки сделаем кнопку в AdvancedHelloWorld нестандартной, подготовив 3 9patch-изображения — для обычной кнопки, нажатого состояния и кнопки в фокусе. Занятие достаточно нудное, но открывает большие возможности.
Важный момент: все 9patch-изображения должны иметь расширение .9.png, иначе наше приложение не узнает, что изображение можно масштабировать по правилам 9patch. Отсюда еще одно ограничение: в папке ресурсов не может быть одновременно двух файлов с одинаковым именем и расширениями .png и .9.png (например, button.png и button.9.png конфликтуют, так как фактически имеют одинаковое имя ресурса — button).

Полезные ссылки


Android Asset Studio на Googlecode: http://android-ui-utils.googlecode.com/hg/asset-studio/dist/index.html
Официальная документация по созданию вложенных меню: http://developer.android.com/guide/topics/ui/menus.html#submenu
Пример с полным перечнем типов настроек: http://www.kaloer.com/android-preferences
Проблема стилизации настроек: http://stackoverflow.com/questions/2615528/preferenceactivity-and-theme-not-applying

Исходные коды.
Share post

Comments 16

    +6
    Отличная статья для новичков. Молодец.
    • UFO just landed and posted this here
      +2
      Отличный старт! Спасибо за статью.
        0
        Ай молодца, да про андроида еще!
          0
          Очень кстати! Как раз собирался заняться программированием под Андроид. Спасибо!
            +3
            Большое спасибо за Android Asset Studio. Не знал что такое существует )
              0
              оно вышло совсем недавно, теперь иконки гораздо проще делать :)
                +2
                да, проект очень молодой, пока в стадии бета. Следить за развитием можно в блоге автора designbycode.tumblr.com

                Всем спасибо за положительные отзывы и отдельно тов. kuzvac за инвайт.
                  0
                  Продолжайте в том же духе, хорошую статью написали:)
              • UFO just landed and posted this here
                  0
                  Спасибо за информацию. Всё-таки на C# можно что-то мобильное писать. А Вам не известно про другие какие-либо платформы, на которых можно си шарпить. Особенно интересует C# под Symbian (пускай и с мега костылями).
                  • UFO just landed and posted this here
                      0
                      К сожалению не совсем. Мне нужен просто C# (не сильверлайт) и платформа для 9.2 (не тач).
                      • UFO just landed and posted this here
                          0
                          Искал сейчас. Нашёл Net60. Проект закрытый, но обучаться наверно можно. Спасибо за надежду.
                  +1
                  Статья хороша для новичко, ничего нового не узнал.но отдельное спасибо за Android Asset Studio

                  Only users with full accounts can post comments. Log in, please.