Özel boyacı

Compose'da, çizilebilecek bir şeyi temsil etmek için Painter nesnesi kullanılır (Android'de tanımlanan Drawable API'lerinin yerine) ve etki ilgili composable'ın ölçümü ve düzeni . CEVAP BitmapPainter, ekranda Bitmap çizebilecek bir ImageBitmap alır.

Çoğu kullanım durumu için yukarıdaki painterResource() kullanıldığında doğru öğenin boyacısı (ör. BitmapPainter veya VectorPainter). Daha fazla arasındaki farklarla ilgili bilgi için ImageBitmap ve ImageVector bölümünü okuyun.

Bir Painter, kesin olarak DrawModifier belirlenen sınırları ve ölçüm ya da sayfa düzeni üzerinde hiçbir etkisi composable.

Özel bir boyacı oluşturmak için Painter sınıfını genişletin ve Özel çizim yapmak için DrawScope erişimine izin veren onDraw yöntemi gösterir. Ayrıca, kullanılacak intrinsicSize politikasını geçersiz kılabilirsiniz. içinde bulunduğu Besteci'yi etkiler:

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
    }
}

Artık özel Painter alanımıza sahip olduğumuza göre kaynak resim şu şekildedir:

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()
)

İki resmi özel bir boyacıyla birleştirmenin sonucu aşağıda görülebilir:

İki resmi birbirinin üzerine yerleştiren Özel Boyacı
Şekil 1: İki görüntüyü birbirinin üzerine çıkaran Özel Boyacı

Özel bir boya ustası Modifier.paint(customPainter) ile de kullanılabilir. bir composable'a çizmek için aşağıdaki adımları uygulayın:

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 **/ }

ziyaret edin.