Сайт разработчика Александр Климова

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

Настройка Spinner

Если хотите настроить Spinner по своему вкусу, то можете посмотреть, как выглядят системные ресурсы для этого компонента. Например, зайдите в папку ...\sdk\platforms\android-18\data\res\drawable-xhdpi и поищите в нём файлы со словом spinner. Вы увидите, что ресурсы реализованы с помощью файлов NinePatch.

Создаём собственный стиль для Spinner

Вы можете создать собственные стили с помощью файлов NinePatch. Создаёте три изображения для различных состояний (можно также добавить четвёртое для состояния disabled).

NinePatch

Далее создаёте xml-файл, описывающий визуальные состояния элемента (normal, selected, pressed, disabled). XML-файл и графика должны находиться в одной папке drawable.

res/drawable/btn_dropdown.xml


<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_window_focused="false" android:state_enabled="true"
        android:drawable="@drawable/btn_dropdown_normal" />
    <item
        android:state_window_focused="false" android:state_enabled="false"
        android:drawable="@drawable/btn_dropdown_normal" />
    <item
        android:state_pressed="true"
        android:drawable="@drawable/btn_dropdown_pressed" />
    <item
        android:state_focused="true" android:state_enabled="true"
        android:drawable="@drawable/btn_dropdown_selected" />
    <item
        android:state_enabled="true"
        android:drawable="@drawable/btn_dropdown_normal" />
    <item
        android:state_focused="true"
        android:drawable="@drawable/btn_dropdown_selected" />
    <item
        android:drawable="@drawable/btn_dropdown_normal" />
</selector>

Затем необходимо прописать новую тему (или отредактировать имеющуюся).

res/values/themes.xml


<style name="Your_Theme_Name" parent="@android:Theme.Light">
      ...
      <item name="android:spinnerStyle">@style/Widget.Spinner</item>
      ...
</style>
<style name="Widget.Spinner" parent="android:Widget">
     <item name="android:background">@drawable/btn_dropdown</item>
     <item name="android:clickable">true</item>
</style>

Осталось прописать в атрибуте android:spinnerStyle созданный стиль, чтобы увидеть красоту.

Лапа вместо треугольника

По умолчанию, у Spinner в правом нижнему углу используется треугольник для раскрытия списка. Покажу другой способ, использующий не файлы NinePatch, а xml-файлы и растровые изображения. Заодно поменяем и внешний вид компонента.

В файле res/values/styles.xml добавим новые строчки для компонента:


<style name="spinner_style">
    <item name="android:background">@drawable/gradient_spinner</item>
    <item name="android:layout_marginLeft">5dp</item>
    <item name="android:layout_marginRight">5dp</item>
    <item name="android:layout_marginBottom">5dp</item>
    <item name="android:paddingLeft">6dp</item>
    <item name="android:paddingTop">4dp</item>
    <item name="android:paddingBottom">4dp</item>
    <item name="android:popupBackground">#DFFFFFFF</item>
</style>

Первая строчка ссылается на ресурс gradient_spinner. Создайте новую папку res/drawable и в ней создайте файл gradient_spinner.xml:


<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item><layer-list>
            <item><shape>
                    <gradient android:angle="90" android:endColor="#B3BBCC" android:startColor="#E8EBEF" android:type="linear" />

                    <stroke android:width="1dp" android:color="#000000" />

                    <corners android:radius="4dp" />

                    <padding android:bottom="2dp" android:left="2dp" android:right="2dp" android:top="2dp" />
                </shape></item>
            <item><bitmap android:gravity="bottom|right" android:src="@drawable/spinner_arrow" />
            </item>
        </layer-list></item>

</selector>

В этом файле есть ссылка на ресурс с растровым изображением spinner_arrow. Создайте в графическом редакторе нужное изображение, которое должно заменить треугольник. В моём случае это будет кошачья лапа. Сохраните рисунок под именем spinner_arrow.png в той же папке drawable. При желании можете добавить дополнительные стили для фокуса, нажатия и т.п. (посмотрите первый пример для образца).

Подключаем созданный стиль:


<Spinner
    android:id="@+id/spinner1"
    style="@style/spinner_style"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

Запускаем пример и любуемся эффектом. Для сравнения ниже добавил второй Spinner с обычным стилем. Мне кажется, наш вариант гораздо интереснее и его надо использовать по умолчанию во всех Android-приложениях.

Spinner

Реклама