Создание атрибутов разметки для собственных компонентов в Android

В этой статье мы разберем, как свойства компонента можно было инициализировать прямо в 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>
И наблюдать следующий результат:
Результат работы VerticalProgressBar

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

Отправить комментарий