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

Как задать свои атрибуты в Custom View

1.6 Junior🔥 132 комментариев
#Android компоненты#UI и вёрстка

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

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

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

Как задать свои атрибуты в Custom View

Для создания пользовательских атрибутов (custom attributes) в Custom View необходимо выполнить несколько ключевых шагов: объявление атрибутов в XML ресурсе, их обработку в классе View и применение в XML-разметке. Это позволяет сделать вашу компоненту гибкой и конфигурируемой прямо из XML, аналогично стандартным View (например, android:text для TextView).

Шаг 1: Определение атрибутов в файле res/values/attrs.xml

Создайте (или добавьте в существующий) файл attrs.xml в директории res/values. Внутри него объявите элемент <declare-styleable> с именем, совпадающим с вашим классом Custom View (обычно это имя класса). Внутри него перечислите атрибуты с помощью элементов <attr>.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="CustomCircleView">
        <!-- Атрибут цвета с предопределенным форматом color -->
        <attr name="circleColor" format="color" />
        <!-- Атрибут размера с форматом dimension -->
        <attr name="circleRadius" format="dimension" />
        <!-- Атрибут с несколькими форматами (например, ссылка или цвет) -->
        <attr name="borderDrawable" format="reference|color" />
        <!-- Атрибут строки -->
        <attr name="labelText" format="string" />
        <!-- Атрибут целого числа -->
        <attr name="strokeWidth" format="integer" />
        <!-- Атрибут булевого значения -->
        <attr name="isFilled" format="boolean" />
        <!-- Атрибут с перечислением (enum) -->
        <attr name="circleStyle">
            <enum name="solid" value="0" />
            <enum name="dashed" value="1" />
            <enum name="dotted" value="2" />
        </attr>
        <!-- Атрибут с флагами (flag) -->
        <attr name="visibilityFlags">
            <flag name="visible" value="0" />
            <flag name="invisible" value="1" />
            <flag name="gone" value="2" />
        </attr>
    </declare-styleable>
</resources>

Ключевые моменты: format определяет тип данных атрибута. Основные форматы: color, dimension, string, integer, boolean, reference, enum, flag. Можно указывать несколько форматов через |.

Шаг 2: Обработка атрибутов в классе Custom View

В конструкторе вашего класса (обычно в конструкторе, принимающем AttributeSet) необходимо получить TypedArray из контекста, используя объявленные атрибуты, и извлечь значения.

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

    private var circleColor: Int = Color.RED
    private var circleRadius: Float = 50f
    private var labelText: String = "Default"

    init {
        if (attrs != null) {
            val typedArray = context.obtainStyledAttributes(
                attrs,
                R.styleable.CustomCircleView,
                defStyleAttr,
                0
            )

            // Извлечение значений с предоставлением default значений
            circleColor = typedArray.getColor(
                R.styleable.CustomCircleView_circleColor,
                Color.RED
            )
            circleRadius = typedArray.getDimension(
                R.styleable.CustomCircleView_circleRadius,
                50f
            )
            labelText = typedArray.getString(
                R.styleable.CustomCircleView_labelText
            ) ?: "Default"

            // Для enum: получаем целое значение
            val style = typedArray.getInt(
                R.styleable.CustomCircleView_circleStyle,
                0
            )

            // Важно: освободить TypedArray после использования
            typedArray.recycle()
        }

        // После получения атрибутов можно, например, настроить Paint
        setupPaint()
    }

    private fun setupPaint() {
        // ... используем circleColor, circleRadius и т.д.
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        // Отрисовка View с использованием кастомных атрибутов
        canvas?.drawCircle(centerX, centerY, circleRadius, paint)
    }
}

Важные детали: obtainStyledAttributes связывает AttributeSet (атрибуты из XML) с вашим declare-styleable. После извлечения всех данных необходимо вызвать recycle() для освобождения ресурсов. Для каждого типа атрибута есть соответствующий метод get (например, getColor, getDimension).

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

В файле layout (например, activity_main.xml) вы можете использовать вашу Custom View и задавать атрибуты через пространство имен app (или любое другое, объявленное в корневом элементе).

<?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-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.example.myapp.CustomCircleView
        android:layout_width="200dp"
        android:layout_height="200dp"
        app:circleColor="@color/blue"
        app:circleRadius="80dp"
        app:labelText="Hello Custom View"
        app:isFilled="true"
        app:circleStyle="dashed" />

</LinearLayout>

Обязательно: Укажите полное имя класса (включая пакет). Атрибуты задаются через app: (или custom: если вы используете другое пространство имен). Система автоматически связывает эти атрибуты с объявленными в attrs.xml.

Дополнительные соображения

  • Наследование атрибутов: Если ваша View наследует от другой, можно использовать defStyleAttr для применения стиля по умолчанию из темы.
  • Обработка сложных типов: Для атрибута format="reference" можно получить Drawable или другой ресурс через getDrawable.
  • Совместимость с Android Studio: Правильно объявленные атрибуты будут отображаться в подсказках автодополнения в XML.
  • Миграция на Jetpack Compose: В Compose концепция атрибутов заменяется параметрами (@Composable функций), но принцип конфигурации остается аналогичным.

Этот подход обеспечивает чистое разделение логики и декларативного описания, делает вашу Custom View удобной для использования другими разработчиками и соответствует стандартным паттернам Android SDK.

Как задать свои атрибуты в Custom View | PrepBro