То-есть народ особо не понимает сам принцип работы тем и аттрибутов.
Попробуем немного разжевать эту тему.
Для начала: что такое вообще стили? Набор значений для аттрибутов.
А где список этих аттрибутов, как получить их значения?
Styleable-ресурсы.
Давайте пока по старинке: создадим свою вьюху:
package habra.tutorial.customwidget; import android.content.Context; import android.util.AttributeSet; import android.view.View; public class HabraWidget extends View { public HabraWidget(Context context) { super(context); } public HabraWidget(Context context, AttributeSet attrs) { super(context, attrs); } public HabraWidget(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } }
Вы никогда не задумывались, что это за последний, третий, аргумент в конструкторе? int defStyle?
У вас будет время подумать, а мы пока создадим свой первый аттрибут, значение которого будет лежать в теме для Activity или даже для всего приложения…
Создаем values/attrs.xml (название не принципиальное, можно хоть в strings.xml)
<?xml version="1.0" encoding="utf-8"?> <resources> <attr name="habraWidgetStyle" format="reference" /> </resources>
В Android имена аттрибутов для стилей для виджетов принято задавать именем виджета в camelCase + постфикс Style.
А format задает, как ни странно, формат значений. Оставим тут reference, т.е. ссылку на ресурc, в данном случае — на стиль.
Теперь модифицируем конструкторы нашего виджета. Сейчас они просто вызывают родительский конструктор.
И теперь фича defStyle — он задает имя аттрибута, по умолчанию будет использоваться значения из стиля, на который ссылается этот аттрибут.
public HabraWidget(Context context) { this(context, null); } public HabraWidget(Context context, AttributeSet attrs) { this(context, attrs, R.attr.habraWidgetStyle); }
Т.е. конструктор HabraWidget(Context) будет вызывать HabraWidget(Context, AttributeSet) со вторым аргументов null,
а он в свою очередь вызывает HabraWidget(Context, AttributeSet, int) с нашим аттрибутом.
Теперь определимся, а что, собственно, наш виджет делать будет? Пусть он рисует простой крест из своих углов:
private final Paint paint; public HabraWidget(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); paint = new Paint(); paint.setColor(0xFF00EEFF); paint.setStyle(Style.FILL_AND_STROKE); } @Override protected void onDraw(Canvas canvas) { canvas.drawLine(0, 0, getWidth(), getHeight(), paint); canvas.drawLine(getWidth(), 0, 0, getHeight(), paint); }
Отлично, но цвет линии жестко указан в коде (0xFF00EEFF), вы думаете о том-же, о чем и я? Вынести в стили!
Сначала создадим styleable с аттрибутом… ну, скажем, lineColor:
attrs.xml
<declare-styleable name="HabraWidget"> <attr name="lineColor" format="color|reference"/> </declare-styleable>
И создадим дефолтовый стиль:
styles.xml
<style name="HabraWidget"> <item name="lineColor">#f00</item> </style>
И как теперь вытащить цвет?
TypedArray:
public HabraWidget(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.HabraWidget, defStyle, R.style.HabraWidget); paint = new Paint(); paint.setColor(a.getColor(R.styleable.HabraWidget_lineColor, 0xFFFF0000)); paint.setStyle(Style.FILL_AND_STROKE); a.recycle(); }
0xFFFF0000 — дефолтный цвет. Можно и передавать какой-нибудь ноль, поскольку дефолтовую тему мы таки указали.
Ну и не забываем сделать recycle после того, как вытащили все данные.
Дальше особенность, касаемая создание layout. Мы привыкли, что все аттрибуты задаются через неймспейс android:.
Но поскольку наши аттрибуты не находятся в пакете android, то и неймспейс другой будет.
Приведу пример:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:habra="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <habra.tutorial.customwidget.HabraWidget android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" habra:lineColor="#00f" /> <habra.tutorial.customwidget.HabraWidget android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" habra:lineColor="#0f0" /> </LinearLayout>
Теперь мы свободно можем задавать цвет линий из разметки.
ссылка на оригинал статьи http://habrahabr.ru/post/157393/
Добавить комментарий