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