Ниже рассказывается как создать кнопки в стиле Twitter Bootstrap для Android приложения. Данный стиль взят для примера что бы разобраться в концпеции создания собственных стилей. Пример кода выложен на github. Репозиторий будет попoлняться примерами для других элементов. Так что можно подписываться.
Android SDK предлагает несколько вариантов для создания собственных стилей.
Начнём с самого простого. Создададим кнопку на основе нескольких графических файлов отображающих отдельные состояни кнопок. (default, selected, focused, pressed и т.д.) Поддерживаются форматы .png, .jpg, или .gif.
Добавляем в активити код для кнопки.
В папке res/drawable создаём файл button_primary_selector.xml
Этот файл делает роутинг графиков в зависимости от текущего состояния кнопки
Добавляем графики для каждого состояния кнопки в ту же папку. Расширение файла указывать не надо. Недостатком данного примера является невозможность динамического скалирования кнопок.
Решаем проблему скалирования элементов следующим образом. В случае кнопки нужны по крайней мере два png файла соответствующие нормальному и нажатому состояниям.
Исходный график нормального состояния для primary button
Конвертация происходит с помощью утилиты draw9patch. Её можно найти в ANDROID_SDK_HOME/tools/.
После запуска перетягиваем график в открывшееся окно. И по краю картинки помечаем пиксели входящие в скалируемого контента. Примерно так
Справа предлагается превью. Если результат удовлетворительный. Через меню сохраняем файл в папку drawable. Повторяем процедуру для графиков всех состояний кнопки.
Подключение кнопки происходит также как в предыдущем примере
Вместо графиков можно описывать элементы с помощью XML.
Пример селектора для двух состояний:
При изменении состояния файл читается сверху вниз и первый элемент с подходящим статусом будет выполнен.
Последний элемент в данном примере будет выполнятся если состояние предыдущих элементов не соответствует состоянию кнопки.
Этот пример можно дополнить для отображения других состояний добавив элементы item с соответствующим атрибутом
Например для selected
Описание состояний можно также вынести в отдельные файлы. Например нажатая кнопка будет описываться так в файле button_primary_pressed.xml
В селекторе расширение (.xml) также не указывается.
Вместо StateList можно также использовать LayerList. Этот подход отличается от предудыщего тем что элементы не имеют атрибута состояния. Все элементы будут отработаны. Последний элемент отрисовывается сверху.
Пример:
В результате получаем
Примеры кода для создания стиля кнопок с помощью StateList и Shape Drawable можно посмотреть здесьandroid-custom-style-ui.
Дополнительная информация и источники можно найти здесь.
Android SDK предлагает несколько вариантов для создания собственных стилей.
Начнём с самого простого. Создададим кнопку на основе нескольких графических файлов отображающих отдельные состояни кнопок. (default, selected, focused, pressed и т.д.) Поддерживаются форматы .png, .jpg, или .gif.
Добавляем в активити код для кнопки.
<Button
android:id="@+id/button_primary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/default_margin"
android:background="@drawable/button_primary_selector"
android:text="Button"
android:textColor="@android:color/white" />
В папке res/drawable создаём файл button_primary_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true" android:drawable="@drawable/button_primary_selected"/>
<item android:state_pressed="true" android:drawable="@drawable/button_primary_pressed"/>
<item android:state_focused="true" android:drawable="@drawable/button_primary_focused"/>
<item android:drawable="@drawable/button_primary_normal"/>
</selector>
Этот файл делает роутинг графиков в зависимости от текущего состояния кнопки
Добавляем графики для каждого состояния кнопки в ту же папку. Расширение файла указывать не надо. Недостатком данного примера является невозможность динамического скалирования кнопок.
Использование формата Nine-Patch File
Решаем проблему скалирования элементов следующим образом. В случае кнопки нужны по крайней мере два png файла соответствующие нормальному и нажатому состояниям.
Исходный график нормального состояния для primary button
Конвертация происходит с помощью утилиты draw9patch. Её можно найти в ANDROID_SDK_HOME/tools/.
После запуска перетягиваем график в открывшееся окно. И по краю картинки помечаем пиксели входящие в скалируемого контента. Примерно так
Справа предлагается превью. Если результат удовлетворительный. Через меню сохраняем файл в папку drawable. Повторяем процедуру для графиков всех состояний кнопки.
Подключение кнопки происходит также как в предыдущем примере
Shape Drawable
Вместо графиков можно описывать элементы с помощью XML.
Пример селектора для двух состояний:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape>
<gradient
android:startColor="#002A80"
android:endColor="#04C"
android:angle="270" />
<stroke
android:width="1dp"
android:color="#04C" />
<corners
android:radius="4dp" />
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" />
</shape>
</item>
<item>
<shape>
<gradient
android:startColor="#006DCC"
android:endColor="#04C"
android:angle="270" />
<stroke
android:width="1dp"
android:color="#04C" />
<corners
android:radius="4dp" />
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" />
</shape>
</item>
</selector>
При изменении состояния файл читается сверху вниз и первый элемент с подходящим статусом будет выполнен.
Последний элемент в данном примере будет выполнятся если состояние предыдущих элементов не соответствует состоянию кнопки.
Этот пример можно дополнить для отображения других состояний добавив элементы item с соответствующим атрибутом
Например для selected
...
android:state_selected="true"
...
Описание состояний можно также вынести в отдельные файлы. Например нажатая кнопка будет описываться так в файле button_primary_pressed.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<gradient
android:startColor="#04C"
android:endColor="#006DCC"
android:angle="270" />
<stroke
android:width="1dp"
android:color="#04C" />
<corners
android:radius="4dp" />
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" />
</shape>
</item>
</selector>
В селекторе расширение (.xml) также не указывается.
Вместо StateList можно также использовать LayerList. Этот подход отличается от предудыщего тем что элементы не имеют атрибута состояния. Все элементы будут отработаны. Последний элемент отрисовывается сверху.
Пример:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<bitmap android:src="@drawable/android_red"
android:gravity="center" />
</item>
<item android:top="10dp" android:left="10dp">
<bitmap android:src="@drawable/android_green"
android:gravity="center" />
</item>
<item android:top="20dp" android:left="20dp">
<bitmap android:src="@drawable/android_blue"
android:gravity="center" />
</item>
</layer-list>
В результате получаем
Примеры кода для создания стиля кнопок с помощью StateList и Shape Drawable можно посмотреть здесьandroid-custom-style-ui.
Дополнительная информация и источники можно найти здесь.