ב-Compose, אובייקט Painter
משמש לייצוג משהו שאפשר לצייר (החלפה לממשקי ה-API של Drawable
שהוגדרו ב-Android) ולהשפיע על המדידה והפריסה של ה-composable התואם שמשתמש בו . BitmapPainter
מקבל ImageBitmap
שיכול לצייר Bitmap
במסך.
ברוב תרחישי השימוש, השימוש ב-painterResource()
שלמעלה מחזיר את ה-painter הנכון לנכס (כלומר BitmapPainter
או VectorPainter
). למידע נוסף על ההבדלים בין השניים, קראו את הקטע ImageBitmap לעומת ImageVector.
Painter
שונה מ-DrawModifier
, שמצויר בגבולות שניתנים לו ולא משפיע על המדידה או על הפריסה של הרכיב הניתן לקיבוץ.
כדי ליצור צייר מותאם אישית, צריך להרחיב את הכיתה Painter
ולהטמיע את השיטה onDraw
, שמאפשרת גישה ל-DrawScope
כדי לצייר גרפיקה בהתאמה אישית. אפשר גם לשנות את הערך של intrinsicSize
, שישפיע על ה-Composable שבו הוא נכלל:
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)
כדי לצייר את התוכן ב-Composable באופן הבא:
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 {:#loading-images}