Относительно недавно мы рассматривали способ, как писать собственые компоненты на примере VerticalProgressBar
. Однако была в той реализации некоторая некрасивость: свойства компонента (такие как progress
и max
) можно было инициализировать только в коде:
mProgressBar = (VerticalProgressBar)findViewById(R.id.progress); mProgressBar.setMax(100); mProgressBar.setProgress(0);
А было бы лучше выставлять их прямо в XML-разметке. В этой статье мы разберем, как это делается.
Новых компонентов выдумывать не будем, рассмотрим тот же VerticalProgressBar
.
Объявление атрибутов
Атрибуты объявляются в ресурсах. Создадим файл attrs.xml
и добавим в него следующее содержимое:
attrs.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="VerticalProgressBar"> <attr name="android:max" /> <attr name="android:progress" /> </declare-styleable> </resources>
У атрибута есть название (name
) и тип (format
). В данном случае мы навесили на наш компонент два стандартных андроидовских атрибута. format
для них указывать не нужно и даже вредно, т.к. возникнет ошибка "Attribute has already been defined". К слову, список стандартных атрибутов можно увидеть в исходниках андроида (~/base/core/res/res/values/public.xml
)
Для полноты картины добавим еще два собственных атрибута — в которых можно будет задавать цвет прогресса:
attrs.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="VerticalProgressBar"> <attr name="android:max" /> <attr name="android:progress" /> <attr name="proceedColor" format="color" /> <attr name="finishedColor" format="color" /> </declare-styleable> </resources>
Тут уже все по-честному, format
задается, а префикс android
не пишется.
Чтение значений
Итак, атрибуты объявлены, нужно их как-то прочитать. Как известно, у View
имеется конструктор со следующей сигнатурой:
View (Context context, AttributeSet attrs)
Он вызывается при создании компонента из XML-разметки. А в параметре attrs
передаются все атрибуты, указанные в разметке для данного компонента. Отсюда-то мы и станем их читать:
VerticalProgressBar.java
public class VerticalProgressBar extends View { public VerticalProgressBar(Context context, AttributeSet attrs) { super(context, attrs); TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.VerticalProgressBar); mProgress = a.getInteger(R.styleable.VerticalProgressBar_android_progress, DEFAULT_PROGRESS); mMax = a.getInteger(R.styleable.VerticalProgressBar_android_max, DEFAULT_MAX); mProceedColor = a.getColor(R.styleable.VerticalProgressBar_proceedColor, DEFAULT_PROCEED_COLOR); mFinishedColor = a.getColor(R.styleable.VerticalProgressBar_finishedColor, DEFAULT_FINISHED_COLOR); } private static final int DEFAULT_PROGRESS = 0; private static final int DEFAULT_MAX = 100; private static final int REMAIN = Color.rgb(49, 49, 49); private static final int DEFAULT_PROCEED_COLOR = Color. rgb(22, 72, 237); private static final int DEFAULT_FINISHED_COLOR = Color.rgb(124, 209, 15); private int mProgress; private int mMax; private int mProceedColor; private int mFinishedColor; ... }
Использование
Теперь в XML-разметке активности можно писать вот так:
main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res/demo.verticalprogress" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="5dip" > <demo.verticalprogress.VerticalProgressBar android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_marginRight="20dip" android:progress="50" android:max="90" /> <demo.verticalprogress.VerticalProgressBar android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_marginRight="20dip" android:progress="20" android:max="60" app:proceedColor="@color/yellow"/> <demo.verticalprogress.VerticalProgressBar android:layout_width="wrap_content" android:layout_height="fill_parent" android:progress="60" android:max="60" app:finishedColor="@color/red"/> </LinearLayout>
И наблюдать следующий результат:
Заключение
Итак, мы рассмотрели, как навешивать на компонент произвольные атрибуты. Причем, как стандартные андроидские, так и собственные.
Ссылки
- Passing custom attributes via XML resource files
- android custom component — возможные проблемы при создании компонентов и пути их решения
- XML Attributes for Custom Views and Layouts in Android OS SDK
- Valid format values for declare-styleable/attr tags — список доступных типов данных для атрибутов
Замечательный пост. Давно ждал новых сообщений от Вас. Спасибо.
ОтветитьУдалитьШикарный блог! Помогает мне в разработке.
ОтветитьУдалитьДарья, спасибо большое!