Pull to refresh

Android UI. Делаем кнопки в стиле Twitter Bootstrap

Reading time 4 min
Views 63K
Ниже рассказывается как создать кнопки в стиле Twitter Bootstrap для Android приложения. Данный стиль взят для примера что бы разобраться в концпеции создания собственных стилей. Пример кода выложен на github. Репозиторий будет попoлняться примерами для других элементов. Так что можно подписываться.


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.

Дополнительная информация и источники можно найти здесь.
Tags:
Hubs:
+8
Comments 18
Comments Comments 18

Articles