Cómo mostrar una imagen recortada en una forma

Puedes ajustar una imagen a una forma recortada y dibujar sombras alrededor del perímetro de la forma para darle un aspecto tridimensional. Esta técnica es útil para crear diseños, como avatares y miniaturas de productos, o mostrar logotipos con formas personalizadas.

Para mostrar una imagen recortada en una forma, debes hacer lo siguiente:

  • Crea la forma.
  • Recorta la imagen en la forma.

Compatibilidad de versiones

Esta implementación requiere que el minSDK de tu proyecto se establezca en el nivel de API 21 o superior.

Dependencias

Crea una forma

Con el siguiente código, se crea una forma personalizada que puede dibujar y renderizar de forma dinámica un polígono redondeado:

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)
    }
}

Puntos clave sobre el código

  • RoundedPolygon.getBounds() define una función de extensión en la clase RoundedPolygon para calcular sus límites.
  • La clase RoundedPolygonShape implementa la interfaz Shape, lo que te permite definir una forma personalizada (un polígono redondeado) en Jetpack Compose.
  • La forma usa un Matrix para administrar las operaciones de escalamiento y traducción para una renderización flexible.
  • La función createOutline() toma un objeto RoundedPolygon, lo escala y lo traduce para que se ajuste a un tamaño determinado, y muestra un objeto Outline que describe la forma final que se dibujará.

Recorta la imagen en una forma

El siguiente código recorta la imagen en un hexágono y agrega una sombra sutil para proporcionar una sensación de profundidad:

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)
    )
}

Puntos clave sobre el código

  • Los objetos RoundedPolygon y RoundedPolygonShape se usan para definir y aplicar una forma hexagonal a la imagen.
  • El código usa graphicsLayer para agregar una sombra basada en la elevación a la imagen. Esto crea una sensación de profundidad y separación visual del fondo.
  • El uso de bloques remember optimiza el rendimiento, ya que garantiza que las definiciones de forma y recorte se calculen solo una vez y se recuerden para las recomposiciones posteriores de la IU.

Resultados

Perro en un hexágono con sombra aplicada alrededor de los bordes
Figura 1: Se aplicó una forma personalizada como clip.

Colecciones que contienen esta guía

Esta guía forma parte de estas colecciones de guías rápidas seleccionadas que abarcan objetivos más amplios de desarrollo de Android:

Descubre técnicas para usar imágenes atractivas y brillantes que le den a tu app para Android un aspecto atractivo.

Tienes preguntas o comentarios

Ve a nuestra página de preguntas frecuentes para obtener información sobre las guías rápidas o comunícate con nosotros para contarnos tu opinión.