在 Compose 中,Painter
对象用于表示可以绘制的内容(替代 Android 中定义的 Drawable
API),并且会影响使用该对象的相应可组合项的测量和布局。BitmapPainter
接受可以在屏幕上绘制 Bitmap
的 ImageBitmap
。
对于大多数用例,使用上面的 painterResource()
会为该资源返回正确的 Painter(即 BitmapPainter
或 VectorPainter
)。如需详细了解两者之间的差异,请参阅 ImageBitmap 与 ImageVector 部分。
Painter
与 DrawModifier
不同,后者在绘制时严格遵守为其指定的边界,并且不会影响可组合项的测量或布局。
如需创建自定义 Painter,请扩展 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() )
通过自定义 Painter 合并这两张图片的输出如下所示:
自定义 Painter 还可以与 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}