Отобразить изображение, обрезанное по фигуре

Вы можете поместить изображение в обрезанную фигуру и нарисовать тени по периметру фигуры, чтобы придать ощущение трехмерности. Этот метод полезен для создания таких дизайнов, как аватары и миниатюры продуктов, а также для отображения логотипов с нестандартными формами.

Чтобы отобразить изображение, обрезанное по фигуре, необходимо сделать следующее:

  • Создайте форму.
  • Прикрепите изображение к фигуре.

Совместимость версий

Для этой реализации требуется, чтобы для minSDK вашего проекта был установлен уровень API 21 или выше.

Зависимости

Создайте фигуру

Следующий код создает пользовательскую фигуру, которая может динамически рисовать и визуализировать закругленный многоугольник:

fun RoundedPolygon.getBounds() = calculateBounds().let { Rect(it[0], it[1], it[2], it[3]) }
class RoundedPolygonShape(
    private val polygon: RoundedPolygon,
    private var matrix: Matrix = Matrix()
) : Shape {
    private var path = Path()
    override fun createOutline(
        size: Size,
        layoutDirection: LayoutDirection,
        density: Density
    ): Outline {
        path.rewind()
        path = polygon.toPath().asComposePath()
        matrix.reset()
        val bounds = polygon.getBounds()
        val maxDimension = max(bounds.width, bounds.height)
        matrix.scale(size.width / maxDimension, size.height / maxDimension)
        matrix.translate(-bounds.left, -bounds.top)

        path.transform(matrix)
        return Outline.Generic(path)
    }
}

Ключевые моменты о коде

  • RoundedPolygon.getBounds() определяет функцию расширения класса RoundedPolygon для вычисления его границ.
  • Класс RoundedPolygonShape реализует интерфейс Shape , позволяющий определить пользовательскую фигуру (закругленный многоугольник) в Jetpack Compose.
  • Фигура использует Matrix для управления операциями масштабирования и перевода для гибкого рендеринга.
  • Функция createOutline() принимает объект RoundedPolygon , масштабирует и переводит его в соответствии с заданным размером и возвращает объект Outline , описывающий конечную форму, которую нужно нарисовать.

Обрезаем изображение по фигуре

Следующий код обрезает изображение до шестиугольника и добавляет тонкую тень, чтобы придать ощущение глубины:

val hexagon = remember {
    RoundedPolygon(
        6,
        rounding = CornerRounding(0.2f)
    )
}
val clip = remember(hexagon) {
    RoundedPolygonShape(polygon = hexagon)
}
Box(
    modifier = Modifier
        .clip(clip)
        .background(MaterialTheme.colorScheme.secondary)
        .size(200.dp)
) {
    Text(
        "Hello Compose",
        color = MaterialTheme.colorScheme.onSecondary,
        modifier = Modifier.align(Alignment.Center)
    )
}

Ключевые моменты о коде

  • Объекты RoundedPolygon и RoundedPolygonShape используются для определения и применения к изображению шестиугольной формы.
  • В коде используется graphicsLayer для добавления к изображению тени на основе высоты. Это создает ощущение глубины и визуального отделения от фона.
  • Использование блоков remember оптимизирует производительность, гарантируя, что определения формы и отсечения вычисляются только один раз и запоминаются для последующих рекомпозиций пользовательского интерфейса.

Результаты

Собака в шестиугольнике с тенью по краям
Рисунок 1. Пользовательская фигура, примененная в качестве клипа.

Коллекции, содержащие это руководство

Это руководство является частью тщательно подобранной коллекции быстрых руководств, охватывающих более широкие цели разработки Android:

Узнайте, как использовать яркие, привлекательные визуальные эффекты, чтобы придать вашему Android-приложению красивый внешний вид.

Есть вопросы или отзывы

Перейдите на нашу страницу часто задаваемых вопросов и узнайте о кратких руководствах или свяжитесь с нами и сообщите нам свои мысли.