Изменение внешнего вида виджета

Serhei Ivanov

Как изменить форму ТеxtView элемента? У меня текст на полупрозрачном прямоугольном фоне. Как можно сделать прямоугольник другой фигурой?

1 ответ

Serhei Ivanov

Все View в Android имеют xml-атрибут android:background (связанный метод: setBackgroundResource()), который позволяет задать желаемый внешний вид виджета для всех возможных состояний: нормальное, нажатое, выделенное, неактивное, в фокусе, отмеченное и др. (полный список).

1.Для того, чтобы получить желаемый внешний вид виджета нужно подготовить, собственно, сам этот вид. Здесь возможны два варианта:

  1. Изображение. Изображение внешнего вида виджета необходимо подготовить в каком то графическом редакторе для всех желаемых состояний: нормальное, нажатое, неактивное и другие, которые вам требуются (не обязательно все, те состояния, для которых вид не будет задан отрабатываться не будут - видимых изменений при этом состоянии вы не увидите). Так как наши виджеты имеют обычно заранее не определенные размеры ( то есть могут увеличиваться или уменьшаться в зависимости от расположенного на них контента, заданных размеров и тд.), то, как правило, изображения эти следует перевести в формат 9-patch ( задать определенные области в которых изображение будет растягиваться, подстраиваясь под текущие размеры, а так же область, в которую будет выводиться контент.Подробнее.) Если виджет имеет только фиксированный размер, то достаточно подготовить несколько аналогичных изображений для разных плотностей экрана.Подробнее. За этот способ выступает возможность получить сложный вид, ограниченный только фантазией художника.

  2. Нарисовать с помощью графических примитивов xml-разметки. Для этого существует xml-атрибут shape( bc соответствующий класс *************), который позволяет нарисовать точки, линии, прямоугольники, овалы и некоторое другое, а так же наложить заливку, градиенты, тени и тому подобное. За этот способ отличное масштабирование, малый размер и некоторое другое, вроде возможности изменять цвет динамически. В качестве недостатка относительная простота изображения.

Подготовленные файлы размещаются в папке res/drawable/, либо аналогичных с квалификаторами, если требуется.

2.После того, как внешний вид готов, нам необходимо создать специальный файл-селектор StateList, который будет регулировать, каким изображениям\шейпам появляться при определенных состояниях виджета:

<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" android:drawable="@drawable/widget_pressed"> <item android:drawable="@drawable/widget_normal">
</item></item></selector>

Здесь задана обработка нажатия (state_pressed) - вся строка говорит: если на виджете фиксируется нажатие (состояние true - истина), то установить в качестве фона виджета изображение\шейп widget_pressed. Последним идет элемент без всяких условий - он соответствует нормальному виду виджета и будет выбран, когда никакое из состояний указанных ранее не было зафиксировано. Выполнение селектора идет сверху-вниз и будет закончено, когда первое попавшиеся сверху состояние совпадет с условием. Данный файл так же распологается в res/drawable/

Если разные виды для определенных состояний не требуются и виджет всегда должен выглядеть одинаково и при касаниях и при неактивности и пр., то создание селектора можно ( и нужно) пропустить. Тогда в качестве фона используется статичное, заранее подготовленное изображение по технологии, описанной в пункте 1.

3.Завершающим штрихом будет установка созданного нами селектора (или статичного фона) (я назвал его custom_background_selector) в качестве фона виджета:

Как правило, если делается кастомный вид для виджета, то этот виджет не один в приложении - тогда повторяющиеся атрибуты, в том числе и новый бэкграунд логично вынести в отдельный стиль (например, для кнопки):

res/values/styles.xml

res/layout/my_layout.xml

licensed under cc by-sa 3.0 with attribution.