In Compose wird ein Painter-Objekt verwendet, um etwas darzustellen, das gezeichnet werden kann (ein Ersatz für die Drawable-APIs, die in Android definiert sind), und um die Messung und das Layout der entsprechenden kombinierbaren Funktion zu beeinflussen, die das Objekt verwendet . Ein
BitmapPainter verwendet ein ImageBitmap, mit dem ein Bitmap auf dem Bildschirm gezeichnet werden kann.
In den meisten Anwendungsfällen wird durch die Verwendung der painterResource() Funktion der richtige
Painter für das Asset zurückgegeben (z. B. BitmapPainter oder VectorPainter). Weitere
Informationen zu den Unterschieden zwischen den beiden finden Sie im
Abschnitt Vergleich von ImageBitmap mit ImageVector.
Ein Painter unterscheidet sich von einem DrawModifier, der nur innerhalb der ihm zugewiesenen Grenzen zeichnet und keinen Einfluss auf die Messung oder das Layout der komponierbaren Funktion hat.
Wenn Sie einen benutzerdefinierten Painter erstellen möchten, erweitern Sie die Klasse Painter und implementieren Sie die Methode onDraw. Diese ermöglicht den Zugriff auf DrawScope zum Zeichnen benutzerdefinierter Grafiken. Sie können auch den Wert intrinsicSize überschreiben, der verwendet wird, um die komponierbare Funktion zu beeinflussen, in der er enthalten ist:
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 } }
Nachdem wir nun unseren benutzerdefinierten Painter haben, können wir jedes beliebige Bild wie folgt über unser Quellbild legen:
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() )
Die folgende Abbildung zeigt die Ausgabe der Kombination der beiden Bilder mit einem benutzerdefinierten Painter:
Ein benutzerdefinierter Painter kann auch mit dem Modifier.paint(customPainter)
verwendet werden, um den Inhalt in einer komponierbaren Funktion zu zeichnen:
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 **/ }
Empfehlungen für Sie
- Hinweis: Linktext wird angezeigt, wenn JavaScript deaktiviert ist
- Vergleich von ImageBitmap mit ImageVector {:#bitmap-vs-vector}
- Grafiken in Compose
- Bilder laden {:#loading-images}