← Назад к вопросам

Как получить кастомные атрибуты в Custom View, созданные в XML?

2.0 Middle🔥 203 комментариев
#Android компоненты#UI и вёрстка

Комментарии (3)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Получение кастомных атрибутов в Custom View

В Android кастомные атрибуты позволяют настраивать поведение и внешний вид пользовательских View непосредственно из XML-разметки. Для их получения используется следующий алгоритм.

Шаг 1: Объявление кастомных атрибутов в res/values/attrs.xml

Сначала создаем файл attrs.xml (если его нет) в папке res/values. В нем объявляем атрибуты с типом и именем:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="CustomView">
        <attr name="customColor" format="color" />
        <attr name="customText" format="string" />
        <attr name="customSize" format="dimension" />
        <attr name="customFlag" format="boolean" />
    </declare-styleable>
</resources>

Здесь:

  • declare-styleable — контейнер для атрибутов View.
  • format — тип данных (color, string, dimension, integer, boolean и др.).

Шаг 2: Использование атрибутов в XML-разметке

В XML указываем namespace приложения и применяем атрибуты:

<com.example.app.CustomView
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:customColor="#FF5722"
    app:customText="Hello Custom View"
    app:customSize="16sp"
    app:customFlag="true" />

Шаг 3: Получение атрибутов в классе Custom View

В конструкторе View используем TypedArray для извлечения значений. Это делается в три этапа: получение TypedArray, чтение значений, обязательное освобождение ресурсов.

class CustomView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    private var customColor: Int = Color.BLACK
    private var customText: String = ""
    private var customSize: Float = 14f
    private var customFlag: Boolean = false

    init {
        attrs?.let { 
            // 1. Получаем TypedArray
            val typedArray = context.theme.obtainStyledAttributes(
                attrs,
                R.styleable.CustomView,
                defStyleAttr,
                0
            )
            
            try {
                // 2. Читаем значения (указываем дефолтные)
                customColor = typedArray.getColor(
                    R.styleable.CustomView_customColor, 
                    Color.BLACK
                )
                customText = typedArray.getString(
                    R.styleable.CustomView_customText
                ) ?: ""
                customSize = typedArray.getDimension(
                    R.styleable.CustomView_customSize, 
                    14f
                )
                customFlag = typedArray.getBoolean(
                    R.styleable.CustomView_customFlag, 
                    false
                )
            } finally {
                // 3. Обязательно освобождаем ресурсы
                typedArray.recycle()
            }
        }
        applyAttributes()
    }

    private fun applyAttributes() {
        // Применяем полученные значения
        setTextColor(customColor)
        textSize = customSize
        // ... остальная логика
    }
}

Ключевые моменты:

  • obtainStyledAttributes() — метод для получения TypedArray. Принимает набор атрибутов из XML, ссылку на declare-styleable, дефолтный стиль и 0 для дефолтного стиля текстовых appearance.
  • TypedArray.recycle() — критически важный вызов в finally. TypedArray использует общий пул ресурсов, и его необходимо освобождать.
  • Дефолтные значения — всегда предоставляйте их в get-методах TypedArray на случай, если атрибут не указан в XML.
  • Null-безопасность — для строковых атрибутов используйте elvis-оператор для обработки null.

Особенности для defStyleAttr:

Если View должна поддерживать стили из темы, используйте третий параметр конструктора:

class CustomView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = R.attr.customViewStyle // Атрибут стиля из темы
) : View(context, attrs, defStyleAttr) {
    // ... инициализация
}

Это позволяет задать дефолтные значения атрибутов через тему приложения.

Пример обработки в Java:

public class CustomView extends View {
    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray ta = context.getTheme().obtainStyledAttributes(
                attrs, R.styleable.CustomView, 0, 0);
        try {
            int color = ta.getColor(R.styleable.CustomView_customColor, Color.BLACK);
            String text = ta.getString(R.styleable.CustomView_customText);
        } finally {
            ta.recycle();
        }
    }
}

Таким образом, процесс получения кастомных атрибутов включает: объявление в XML, использование в разметке и извлечение через TypedArray с обязательным вызовом recycle(). Это основа кастомизации View в Android.