Dans Compose, un objet Painter
sert à représenter un élément qui peut être dessiné (il remplace les API Drawable
définies dans Android) et à influencer la mesure et la mise en page du composable correspondant qui l'utilise. Un BitmapPainter
prend un ImageBitmap
qui peut dessiner un Bitmap
à l'écran.
Dans la plupart des cas, l'utilisation de painterResource()
ci-dessus renvoie l'objet Painter approprié pour l'élément (par exemple, BitmapPainter
ou VectorPainter
). Pour en savoir plus sur les différences entre les deux, consultez la section ImageBitmap et ImageVector.
Un objet Painter
est différent d'un DrawModifier
, qui dessine strictement dans les limites qui lui sont fournies et qui n'a aucune influence sur la mesure ni la mise en page du composable.
Pour créer un objet Painter personnalisé, développez la classe Painter
et implémentez la méthode onDraw
, qui permet d'accéder à DrawScope
pour dessiner des éléments graphiques personnalisés. Vous pouvez également remplacer intrinsicSize
, qui sera utilisé pour influencer le composable dans lequel il se trouve :
class OverlayImagePainter constructor( private val image: ImageBitmap, private val imageOverlay: ImageBitmap, private val srcOffset: IntOffset = IntOffset.Zero, private val srcSize: IntSize = IntSize(image.width, image.height), private val overlaySize: IntSize = IntSize(imageOverlay.width, imageOverlay.height) ) : Painter() { private val size: IntSize = validateSize(srcOffset, srcSize) override fun DrawScope.onDraw() { // draw the first image without any blend mode drawImage( image, srcOffset, srcSize, dstSize = IntSize( this@onDraw.size.width.roundToInt(), this@onDraw.size.height.roundToInt() ) ) // draw the second image with an Overlay blend mode to blend the two together drawImage( imageOverlay, srcOffset, overlaySize, dstSize = IntSize( this@onDraw.size.width.roundToInt(), this@onDraw.size.height.roundToInt() ), blendMode = BlendMode.Overlay ) } /** * Return the dimension of the underlying [ImageBitmap] as it's intrinsic width and height */ override val intrinsicSize: Size get() = size.toSize() private fun validateSize(srcOffset: IntOffset, srcSize: IntSize): IntSize { require( srcOffset.x >= 0 && srcOffset.y >= 0 && srcSize.width >= 0 && srcSize.height >= 0 && srcSize.width <= image.width && srcSize.height <= image.height ) return srcSize } }
Maintenant que nous avons notre Painter
personnalisé, nous pouvons superposer n'importe quelle image sur notre image source comme suit :
val rainbowImage = ImageBitmap.imageResource(id = R.drawable.rainbow) val dogImage = ImageBitmap.imageResource(id = R.drawable.dog) val customPainter = remember { OverlayImagePainter(dogImage, rainbowImage) } Image( painter = customPainter, contentDescription = stringResource(id = R.string.dog_content_description), contentScale = ContentScale.Crop, modifier = Modifier.wrapContentSize() )
Le résultat de la combinaison des deux images avec un objet Painter personnalisé est illustré ci-dessous :
Un objet Painter personnalisé peut aussi être utilisé avec Modifier.paint(customPainter)
pour dessiner du contenu dans un composable comme suit :
val rainbowImage = ImageBitmap.imageResource(id = R.drawable.rainbow) val dogImage = ImageBitmap.imageResource(id = R.drawable.dog) val customPainter = remember { OverlayImagePainter(dogImage, rainbowImage) } Box( modifier = Modifier.background(color = Color.Gray) .padding(30.dp) .background(color = Color.Yellow) .paint(customPainter) ) { /** intentionally empty **/ }
Recommandations personnalisées
- Remarque : Le texte du lien s'affiche lorsque JavaScript est désactivé
- ImageBitmap et ImageVector {:#bitmap-vs-vector}
- Éléments graphiques dans Compose
- Chargement d'images {:#loading-images}