在 Compose 中,Painter
物件用於表示可繪製的內容 (取代 Android 中定義的 Drawable
API),並且會影響使用該物件的對應可組合項的尺寸和版面配置。BitmapPainter
會採用可在畫面上繪製 Bitmap
的 ImageBitmap
。
在大多數用途上,使用上述的 painterResource()
會傳回素材資源的正確繪圖工具 (例如 BitmapPainter
或是 VectorPainter
)。如要進一步瞭解這兩者之間的差異,請參閱 ImageBitmap 與 ImageVector 一節。
Painter
與 DrawModifier
不同,後者只會在指定的邊界範圍內繪製,不會影響可組合項的尺寸或版面配置。
如要建立自訂繪圖工具,只要擴充 Painter
類別並實作 onDraw
方法,即可存取 DrawScope
以繪製自訂圖形。您也可以覆寫 intrinsicSize
,用於影響其內含的可組合項:
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 } }
現在我們已建立自訂 Painter
,可以將任何圖片重疊在來源圖片上方,如下所示:
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() )
結合兩張圖片與自訂繪圖工具的輸出內容如下所示:
自訂繪圖工具也可以與 Modifier.paint(customPainter)
搭配使用,將內容繪製到可組合項中,如下所示:
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 **/ }
為您推薦
- 注意:系統會在 JavaScript 關閉時顯示連結文字
- ImageBitmap 與 ImageVector {:#bitmap-vs-vector}
- Compose 中的圖形
- 載入圖片 {:#loading-images}