Afficher une image découpée selon une forme

Vous pouvez adapter une image à une forme découpée et dessiner des ombres autour du périmètre de la forme pour lui donner un aspect tridimensionnel. Cette technique est utile pour créer des conceptions telles que des avatars et des miniatures de produits, ou pour afficher des logos avec des formes personnalisées.

Pour afficher une image rognée dans une forme, procédez comme suit:

  • Créez la forme.
  • Découpez l'image selon la forme.

Compatibilité des versions

Cette implémentation nécessite que la version minimale du SDK de votre projet soit définie sur le niveau d'API 21 ou supérieur.

Dépendances

Créer une forme

Le code suivant crée une forme personnalisée pouvant dessiner et afficher dynamiquement un polygone arrondi:

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

Points clés concernant le code

  • RoundedPolygon.getBounds() définit une fonction d'extension sur la classe RoundedPolygon pour calculer ses limites.
  • La classe RoundedPolygonShape implémente l'interface Shape, ce qui vous permet de définir une forme personnalisée (un polygone arrondi) dans Jetpack Compose.
  • La forme utilise un Matrix pour gérer les opérations de mise à l'échelle et de traduction afin d'obtenir un rendu flexible.
  • La fonction createOutline() reçoit un objet RoundedPolygon, le met à l'échelle et le traduit pour qu'il s'adapte à une taille donnée, puis renvoie un objet Outline qui décrit la forme finale à dessiner.

Découper l'image selon une forme

Le code suivant recadre l'image en un hexagone et ajoute une ombre portée subtile pour donner une impression de profondeur:

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

Points clés concernant le code

  • Les objets RoundedPolygon et RoundedPolygonShape permettent de définir et d'appliquer une forme hexagonale à l'image.
  • Le code utilise graphicsLayer pour ajouter une ombre basée sur l'élévation à l'image. Cela crée un sentiment de profondeur et de séparation visuelle de l'arrière-plan.
  • L'utilisation de blocs remember optimise les performances en veillant à ce que les définitions de forme et de découpage ne soient calculées qu'une seule fois et mémorisées pour les recompositions ultérieures de l'UI.

Résultats

Chien dans un hexagone avec une ombre appliquée autour des bords
Figure 1. Forme personnalisée appliquée en tant qu'extrait.

Collections contenant ce guide

Ce guide fait partie de ces collections de guides rapides sélectionnées qui couvrent des objectifs de développement Android plus larges:

Découvrez des techniques pour utiliser des visuels lumineux et attrayants afin de donner à votre application Android une belle apparence.

Vous avez des questions ou des commentaires ?

Consultez notre page des questions fréquentes et découvrez les guides rapides, ou contactez-nous pour nous faire part de vos commentaires.