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

Как сделать круглую View

1.3 Junior🔥 191 комментариев
#UI и вёрстка

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

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

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

Как сделать круглую View в Android

Создание круглой View — распространённая задача в разработке под Android, особенно при работе с аватарами, индикаторами или элементами дизайна Material. Есть несколько подходов, выбор которых зависит от требований к производительности, гибкости и версии Android.

Основные способы

1. Использование CardView (простой и рекомендуемый способ)

CardView из библиотеки Material Design позволяет легко задать скругление через атрибут app:cardCornerRadius. Чтобы сделать View полностью круглой, радиус должен быть равен половине её размера.

<androidx.cardview.widget.CardView
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="100dp"
    android:layout_height="100dp"
    app:cardCornerRadius="50dp" <!-- Половина размера -->
    android:elevation="4dp">
    
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/avatar" />
</androidx.cardview.widget.CardView>

Преимущества: Встроенная поддержка теней (elevation), обратная совместимость через библиотеку поддержки. Недостатки: Дополнительная вложенность в layout.

2. Настройка фона с помощью Shape Drawable

Можно создать XML-ресурс в res/drawable/circle_background.xml, определяющий форму круга.

<!-- res/drawable/circle_background.xml -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    <solid android:color="@color/blue" />
    <size android:width="100dp" android:height="100dp" />
</shape>

Затем назначить этот drawable как фон для любой View (ImageView, TextView и т.д.):

<ImageView
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:background="@drawable/circle_background"
    android:src="@drawable/avatar"
    android:scaleType="centerCrop" />

Важно: Для ImageView также потребуется android:scaleType="centerCrop", чтобы изображение масштабировалось и заполняло круг. Если нужно обрезать само изображение (а не фон), см. пункт 4.

3. Программное создание через Paint и Canvas (кастомная View)

Для полного контроля (например, анимации радиуса) можно создать собственную CustomView, переопределив метод onDraw().

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

    private val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.RED
        style = Paint.Style.FILL
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        val radius = (width.coerceAtMost(height) / 2).toFloat()
        canvas.drawCircle(width / 2f, height / 2f, radius, paint)
    }
}

Применение: Полезно для динамических кругов, прогресс-индикаторов.

4. Обрезка изображения в ImageView с помощью ClipToOutline (API 21+)

Самый современный и производительный способ для обрезки Bitmap внутри ImageView — использование свойства clipToOutline и outlineProvider.

val imageView: ImageView = findViewById(R.id.imageView)
imageView.apply {
    outlineProvider = object : ViewOutlineProvider() {
        override fun getOutline(view: View, outline: Outline) {
            val radius = (view.width.coerceAtMost(view.height) / 2).toFloat()
            outline.setRoundRect(0, 0, view.width, view.height, radius)
        }
    }
    clipToOutline = true
}

Для удобства можно создать функцию-расширение:

fun ImageView.makeCircle() {
    outlineProvider = object : ViewOutlineProvider() {
        override fun getOutline(view: View, outline: Outline) {
            val radius = (view.width.coerceAtMost(view.height) / 2).toFloat()
            outline.setRoundRect(0, 0, view.width, view.height, radius)
        }
    }
    clipToOutline = true
}

Важно: Этот метод работает только с фактически отрисованным View, поэтому вызов должен производиться после того, как View измерил свои размеры (например, в onWindowFocusChanged или используя ViewTreeObserver).

Ключевые рекомендации

  • Для статических элементов (аватары, кнопки) используйте CardView или Shape Drawable — это просто и эффективно.
  • Для обрезки изображений (фотографий пользователей) предпочтительнее ClipToOutline, так как он использует аппаратное ускорение и не создаёт промежуточных Bitmap.
  • Избегайте программного создания масок через BitmapShader или Xfermode для обрезки изображений в реальном времени — это может негативно сказаться на производительности.
  • Для динамических круговых прогресс-баров лучше подойдёт кастомная View с переопределённым onDraw().
  • Всегда включайте android:antialias="true" для drawable или Paint.ANTI_ALIAS_FLAG в коде, чтобы сгладить края круга.

Правильный выбор метода зависит от конкретного сценария: ClipToOutline оптимален для обрезки контента, CardView — для карточек с тенями, а Shape Drawable — для простых фоновых элементов.

Как сделать круглую View | PrepBro