في أداة Compose، يتم استخدام عنصر Painter
لتمثيل عنصر يمكن رسمه
(وهو بديل لواجهات برمجة تطبيقات Drawable
المحدّدة في Android) والتأثير في
قياس وتنسيق العنصر القابل للتجميع المقابل الذي يستخدمه . يأخذ
BitmapPainter
ImageBitmap
يمكنه رسم Bitmap
على الشاشة.
في معظم حالات الاستخدام، يؤدي استخدام العنصر 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}
- الرسومات في ميزة "إنشاء"
- جارٍ تحميل الصور {:#loading-images}