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