In Compose, un oggetto Painter viene utilizzato per rappresentare un elemento che può essere disegnato (un sostituto delle API Drawable definite in Android) e influenzare la misurazione e il layout del composable corrispondente che lo utilizza . Un BitmapPainter accetta un ImageBitmap che può disegnare un Bitmap sullo schermo.
Per la maggior parte dei casi d'uso, l'utilizzo della funzione painterResource() restituisce il painter corretto per l'asset (ad esempio BitmapPainter o VectorPainter). Per ulteriori informazioni sulle differenze tra i due, leggi la sezione ImageBitmap e ImageVector.
Un Painter è diverso da un DrawModifier, che disegna rigorosamente entro i limiti assegnati e non influisce sulla misurazione o sul layout del composable.
Per creare un painter personalizzato, estendi la classe Painter e implementa il metodo onDraw, che consente l'accesso a DrawScope per disegnare grafica personalizzata. Puoi anche eseguire l'override di intrinsicSize, che verrà utilizzato per
influenzare il componibile in cui è contenuto:
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 } }
Ora che abbiamo il nostro Painter personalizzato, possiamo sovrapporre qualsiasi immagine alla nostra immagine di origine come segue:
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() )
La figura seguente mostra l'output della combinazione delle due immagini con un painter personalizzato:
È possibile utilizzare un painter personalizzato anche con Modifier.paint(customPainter)
per disegnare i contenuti in un composable come segue:
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 **/ }
Consigliati per te
- Nota: il testo del link viene visualizzato quando JavaScript è disattivato
- ImageBitmap rispetto a ImageVector {:#bitmap-vs-vector}
- Grafica in Compose
- Caricamento delle immagini {:#loading-images}