Кастомный элемент EditText в Android

При разработке приложения для Android, хотелось бы сохранить цветовую схему элементов. Рассмотрим как это сделать для элемента EditText.

Шаг 1. Подготовка

Создадим обычный Android проект и добавим два элемента EditText:

<EditText
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:id="@+id/editText" />

<EditText
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:id="@+id/editText2"
       android:paddingTop="50dp"/>

Зачем нам два элемента EditText? Что бы наглядно увидеть состояние элемента. На самом деле их 5:

1. default — стандартное;

2. active — активное;

3. focused — сфокусированное;

4. disable — запрещенное;

5. disable_focused — запрещенное сфокусированное.

но мы рассмотрим первые два, для остальных всё аналогично.

Итак, запустим приложение и на нашем Layout’е увидим два EditText‘а. Если мы захотим что то написать в одном из них и нажмем на него — состояние элемента станет Active:

EditTexts

Предположим, что для сохранения цветовой схемы в приложении, выделение линии EditText’а в активном состоянии должно быть фиолетовым (#5b009c). С этого момента всё стало не так просто, как хотелось бы :)

Покопавшись в SDK, можно найти найти такой ресурс:

edittextHolo

Это исходник для поля EditText. По периметру изображения есть красные и черные полосы, отвечающие за изменение размера. То есть, если EditText требуется увеличить по ширине, из картинки выбирается кусок, помеченный черными полосками сверху и снизу и растягивается по длине. При этом в растягивании участвует только определенная область, тем самым не изменяя размер углам EditTex’а. Аналогично изменяется и по высоте. Красные линии — это обязательные отступы.

Итак, мы хотим изменить цвет для активного элемента. Можно перерисовать это изображение и загрузить в проект, но ведь не все дружат с графическими редакторами или может быть просто лень ;)

Для этих целей есть отличный web-сервис: Android Holo Colors Generator

В поле Theme Name следует указать название темы оформление, я назову EditTextStyle. Далее выбираем цвет:

Android Holo Colors

И ниже значение EditText ставим на «YES».

Как видим ниже, сервис сгенерировал для нас ресурсы:

Android Holo Colors - Google Chrome 2014-07-11 11.39.52

 

Осталось только их скачать и добавить в проект. Жмем на кнопку «Download .ZIP» и переходим к следующему шагу.

 

Шаг 2. Прикручиваем кастомный стиль

Распакуем полученный архив и посмотрим, что в нем есть. Нас будут интересовать только папки Drawable:

res 2014-07-11 11.47.27

Расфасуем наши ресурсы по папкам проекта. Тут всё просто, и в итоге выглядит вот так:

MyApp - [E__temp_IdeaProjects_MyApp] - [app] - ..._app_src_main_res_layout_activity_main.xml - IntelliJ IDEA 13.1.2 2014-07-11 11.50.05

Структура имени файлов такова: [edittextstyle]_[textfield_activated]_[holo_light].[9].png

  1. [edittextstyle] — имя нашей темы;
  2. [textfield_activated] — полное название состояния;
  3. [holo_light] — имя родительской темы;
  4. [9] — номер ресурса в SDK.

Однако, само по себе приложение не поймет что нужно брать именно эти ресурсы и поэтому следует явно указать это. Создадим папку «drawable» а в ней файл «edittextstyle_edit_text_holo_light.xml» (если очень лень, то можно конечно всё это взять с архива.. но это же слишком просто, верно?)

Что нужно написать в этом файле? «Там уже всё написано» — скажите вы.. Но ведь следует в этом разобраться!

Как правило хорошего тона и юзабилити приложения, следует давать пользователю обратную связь, в нашем же случае это показать какой элемент сейчас активен. Для реализации такой обратной связи используется паттерн Selector. Суть Selector’а — это задание различного стилевого оформления для различных состояний выбираемого элемента.

Внутри Selector’a находятся элементы Item, а внутри Item — атрибуты, которые говорят, имеет ли элемент активное/фокусированное/запрещенное состояние и ссылку на соответствующий ресурс. 

<?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/edittextstyle_textfield_default_holo_light" />
    <item
            android:state_window_focused="false"
            android:state_enabled="false"
            android:drawable="@drawable/edittextstyle_textfield_disabled_holo_light" />
    <item
            android:state_enabled="true"
            android:state_focused="true"
            android:drawable="@drawable/edittextstyle_textfield_activated_holo_light" />
    <item
            android:state_enabled="true"
            android:state_activated="true"
            android:drawable="@drawable/edittextstyle_textfield_focused_holo_light" />
    <item
            android:state_focused="true"
            android:drawable="@drawable/edittextstyle_textfield_disabled_focused_holo_light" />
</selector>

 

Ничего не работает?

Действительно, при запуске приложения ничего не изменится. Почему так? Потому что мы не указали элементам EditText на нашем Layout’е, что нужно использовать эти стили. Открываем activity_main.xml и дописываем в каждый элемент EditText следующий атрибут:

android:background="@drawable/edittextstyle_edit_text_holo_light"

Проверим работу приложения:

Genymotion for personal use - Google Nexus 5 - 4.4.2 - API 19 - 1080x1920 (1080x1920, 480dpi) - 192.168.56.101 2014-07-11 12.28.55

 

Ура! Все работает, можно наградить себя печеньками ;)

 

Лайфхак

Что бы не потерять наш цвет и использовать его где то в других местах, я добавил значение в файле strings.xml

<color name="my_color">#5b009c</color>

PS:

Если вы были внимательны, то должны были заметить, что сервис Android Holo Colors Generator позволяет кастомизировать цвета не только для элемента EditText, но также и для других элементов. 

Конечно, это довольно таки простой способ кастомизации, существуют более серьезные методы решения этой задачи. Например можно все прорисовать с помощью графики:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
 android:shape="rectangle" android:padding="10dp">
<solid android:color="#4C000000"/>
    <corners android:bottomRightRadius="5dp"
             android:bottomLeftRadius="5dp"
             android:topLeftRadius="5dp"
             android:topRightRadius="5dp"/>
</shape>

Тут придется повозится больше, однако в таком случае у нас есть практически безграничные возможности отрисовки, но это уже совсем другая история… :)

Урок создан: 11 июля 2014 | Просмотров: 15471 | Автор: Александр Многосмыслов | Правила перепечатки


Добавить комментарий

Добавить комментарий

Ваш e-mail не будет опубликован.

Комментарии:

  • 05 февраля 2015 в 07:39

    Павел

    #5b009c правильно писать в color.xml

  • 03 ноября 2015 в 02:34

    Константин

    Помоему будет лучшая практика кодом отрисовать EditText без использования графических ресурсов.

    • 09 февраля 2016 в 22:01

      Иван

      А как это можно сделать?

  • 25 ноября 2016 в 21:56

    Дмитрий

    По-моему с приходом Material Design неактуально использование Holo цветов и тем) Но за статью +