In Compose, un oggetto Painter
viene utilizzato per rappresentare qualcosa 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
prende un ImageBitmap
che può disegnare un Bitmap
sullo schermo.
Nella maggior parte dei casi d'uso, l'utilizzo di painterResource()
riportato sopra restituisce il pittore
corretto per l'asset (ad es. BitmapPainter
o VectorPainter
). Per ulteriori
informazioni sulle differenze tra i due, leggi la sezione ImageBitmap e ImageVector.
Un Painter
è diverso da un DrawModifier
, che attrae rigorosamente
i limiti che gli vengono assegnati e non ha alcuna influenza sulla misurazione o sul layout
del componibile.
Per creare un pittore personalizzato, estendi la classe Painter
e implementa il
metodo onDraw
, che consente l'accesso all'elemento DrawScope
per disegnare grafiche
personalizzate. Puoi anche sostituire intrinsicSize
, che verrà utilizzato per influenzare il Composable 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 all'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() )
Di seguito è mostrato l'output della combinazione delle due immagini con un pittore personalizzato:
Un pittore personalizzato può essere utilizzato 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 e ImageVector {:#bitmap-vs-vector}
- Grafica in Compose
- Caricamento delle immagini {:#loading-images}