Часто, интерфейс даже очень популярных 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 файлах. Сделаем один такой файл для нашего главного окна: resmenumain_menu.xml
Два момента:
Если количество пунктов меню больше 6, 6-й и следующие элементы объединяются в дополнительное меню. Пример можно посмотреть в стандартном браузере.
Меню может быть вложенным, но не более одного уровня. Для описания вложенного меню добавляется тег menu в качестве дочернего к тому элементу, который будет «разворачиваться».
При создании меню первым делом стоит поискать иконки в стандартном наборе. Все они есть в установленном SDK — android-sdk-windowsplatformsandroid-1.6dataresdrawableic_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. В resxml создем settings.xml:
xmlns:android="http://schemas.android.com/apk/res/android">
android:title="@string/settings_general">
android:key="center_message"
android:title="@string/center_message"
android:summary="@string/center_message_summary"
android:persistent="true"
android:defaultValue="true"/>
android:key="text_message"
android:title="@string/text_message"
android:summary="@string/text_message_summary"
android:defaultValue="@string/hello_world"
android:persistent="true"/>
Набор поддерживаемых настроек не очень широкий, но основные потребности он покроет. Устанавливая флаг «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).