Oluşturulan Grafikler

Pek çok uygulamanın ekranda çizilen çizgiyi tam olarak kontrol edebilmesi gerekir. tıklayın. Bu, ekrana bir kutu veya daire yerleştirmek kadar küçük yerine koymanız gerekmeyebilir, bunun yerine üzerinde birçok farklı stilde ekleyebilirsiniz.

Değiştiriciler ve DrawScope içeren temel çizim

Oluşturma'da özel bir şey çizmenin temel yolu, Modifier.drawWithContent, Modifier.drawBehind ve Modifier.drawWithCache gibi değiştiricileri kullanmaktır.

Örneğin, kompozisyonunuzun arkasında bir şey çizmek için çizim komutlarını yürütmeye başlamak üzere drawBehind değiştiricisini kullanabilirsiniz:

Spacer(
    modifier = Modifier
        .fillMaxSize()
        .drawBehind {
            // this = DrawScope
        }
)

Tek ihtiyacınız çizim yapan bir composable ise Canvas composable. Canvas bileşeni, Modifier.drawBehind etrafında kullanışlı bir sarmalayıcıdır. Canvas öğesini, diğer tüm Oluştur kullanıcı arayüzü öğelerinde yaptığınız gibi düzeninize yerleştirirsiniz. Canvas içinde, stil ve konumları üzerinde hassas kontrol sahibi olarak öğeler çizebilirsiniz.

Tüm çizim değiştiricileri, kapsamlı bir çizim ortamı olan DrawScope'ı gösterir. durumunu korur. Bu, bir grup kullanıcı için parametreleri grafik öğeleridir. DrawScope, DrawScope'nin mevcut boyutlarını belirten bir Size nesnesi olan size gibi çeşitli yararlı alanlar sağlar.

Bir şey çizmek için DrawScope'teki birçok çizim işlevinden birini kullanabilirsiniz. Örneğin, aşağıdaki kodda gösterildiği gibi, aşağıdaki kod snippet'inin sol üst köşesine ekran:

Canvas(modifier = Modifier.fillMaxSize()) {
    val canvasQuadrantSize = size / 2F
    drawRect(
        color = Color.Magenta,
        size = canvasQuadrantSize
    )
}

Ekranın dörtte birini kaplayan beyaz bir arka plan üzerine çizilmiş pembe dikdörtgen
Şekil 1. Compose'da Tuval kullanılarak çizilen dikdörtgen.

Farklı çizim değiştiricileri hakkında daha fazla bilgi edinmek için Grafik Değiştiriciler bölümüne bakın. belgelerinden faydalanabilirsiniz.

Koordinat sistemi

Ekranda bir şey çizmek için ofseti (x ve y) ve boyutunu bilmeniz gerekir öğedir. DrawScope üzerindeki çizim yöntemlerinin çoğunda konum ve boyut, varsayılan parametre değerleri ile sağlanır. Varsayılan parametreler genellikle öğeyi kanvasta [0, 0] noktasına konumlandırın ve bir varsayılan değer belirtin tüm çizim alanını kaplayan size (yukarıdaki örnekte gösterildiği gibi) ile dikdörtgen sol üste yerleştirilir. Öğenizin boyutunu ve konumunu ayarlamak için Oluştur'daki koordinat sistemini anlamanız gerekir.

Koordinat sisteminin başlangıç noktası ([0,0]), bir grafiktir. x sağa hareket ettikçe, y hareket ettikçe artar aşağı doğru yükseliyor.

Sol üst [0, 0] ve sağ alt [genişlik, yükseklik] koordinat sistemini gösteren ızgara
Şekil 2. Çizim koordinat sistemi / çizim ızgarası.

Örneğin, bir tabletin sağ üst köşesinden çapraz bir çizgi çizmek sol alt köşede görmek isterseniz DrawScope.drawLine() işlevini kullanın ve ilgili x ve y konumları:

Canvas(modifier = Modifier.fillMaxSize()) {
    val canvasWidth = size.width
    val canvasHeight = size.height
    drawLine(
        start = Offset(x = canvasWidth, y = 0f),
        end = Offset(x = 0f, y = canvasHeight),
        color = Color.Blue
    )
}

Temel dönüşümler

DrawScope, çizim komutlarının nerede veya nasıl yürütüleceğini değiştirmek için dönüşümler sunar.

Ölçek

Tekliflerinizi otomatikleştirmek ve optimize etmek için DrawScope.scale() sayısını bir çarpan ile artırın. scale() gibi işlemler, ilgili lambda içindeki tüm çizim işlemleri için geçerlidir. Örneğin, Örneğin, aşağıdaki kod scaleX değerini 10 kez, scaleY değerini ise 15 kez artırır kez:

Canvas(modifier = Modifier.fillMaxSize()) {
    scale(scaleX = 10f, scaleY = 15f) {
        drawCircle(Color.Blue, radius = 20.dp.toPx())
    }
}

Düzensiz şekilde ölçeklendirilmiş bir daire
Şekil 3. Canvas'ta bir daireye ölçek işlemi uygulanıyor.

Çeviri

Tekliflerinizi otomatikleştirmek ve optimize etmek için DrawScope.translate() tuşuna basarak çizim işlemlerinizi yukarı, aşağı, sola veya sağa doğru hareket ettirebilirsiniz. Örneğin, aşağıdaki kod çizimi 100 piksel sağa ve 300 piksel yukarı taşır:

Canvas(modifier = Modifier.fillMaxSize()) {
    translate(left = 100f, top = -300f) {
        drawCircle(Color.Blue, radius = 200.dp.toPx())
    }
}

Merkezden ayrılan bir daire
Şekil 4. Canvas'ta bir çevreye çeviri işlemi uygulanıyor.

Döndür

Tekliflerinizi otomatikleştirmek ve optimize etmek için DrawScope.rotate() kullanarak çizim işlemlerinizi bir pivot nokta etrafında döndürün. Örneğin, aşağıdaki kod bir dikdörtgeni 45 derece döndürür:

Canvas(modifier = Modifier.fillMaxSize()) {
    rotate(degrees = 45F) {
        drawRect(
            color = Color.Gray,
            topLeft = Offset(x = size.width / 3F, y = size.height / 3F),
            size = size / 3F
        )
    }
}

Ekranın ortasında 45 derece döndürülmüş dikdörtgen bir telefon
Şekil 5. Geçerli çizim kapsamına, dikdörtgeni 45 derece döndüren bir döndürme işlemi uygulamak için rotate() kullanılır.

İçe doğru

Mevcut DrawScope'ın varsayılan parametrelerini ayarlamak için DrawScope.inset()'u kullanarak çizim sınırlarını değiştirin ve çizimleri buna göre çevirin:

Canvas(modifier = Modifier.fillMaxSize()) {
    val canvasQuadrantSize = size / 2F
    inset(horizontal = 50f, vertical = 30f) {
        drawRect(color = Color.Green, size = canvasQuadrantSize)
    }
}

Bu kod, çizim komutlarına etkili bir şekilde dolgu ekler:

Etrafı doldurulmuş bir dikdörtgen
Şekil 6. Çizim komutlarına iç içe yerleştirilmiş resim uygulama.

Birden fazla dönüşüm

Çizimlerinize birden çok dönüşüm uygulamak için DrawScope.withTransform() işlevi, istediğiniz tüm değişiklikleri birleştiren tek bir dönüşüm uygular. Kullanım withTransform(), kullanıcılara iç içe yerleştirilmiş çağrılar yapmaktan daha verimlidir çünkü tüm dönüşümler tek bir ekranda yazması ve her bir mesajı kaydetmesi gereken tek bir işlemin dönüşümlerinin nasıl yapıldığını anlatır.

Örneğin, aşağıdaki kod dikdörtgene hem bir kaydırma hem de döndürme işlemi uygular:

Canvas(modifier = Modifier.fillMaxSize()) {
    withTransform({
        translate(left = size.width / 5F)
        rotate(degrees = 45F)
    }) {
        drawRect(
            color = Color.Gray,
            topLeft = Offset(x = size.width / 3F, y = size.height / 3F),
            size = size / 3F
        )
    }
}

Ekranın kenarına kaydırılmış, döndürülmüş bir dikdörtgen içeren telefon
Şekil 7. withTransform hareketini kullanarak hem döndürme hem de çevirme işlemi uygulayın. Dikdörtgeni döndürüp sola kaydırın.

Genel çizim işlemleri

Metin çizme

Compose'da metin çizmek için genellikle Text composable'ı kullanabilirsiniz. Ancak, DrawScope içindeyseniz veya metninizi manuel olarak çizmek istiyorsanız özelleştirilebilir olması için DrawScope.drawText() yöntemidir.

Metin çizmek için rememberTextMeasurer kullanarak bir TextMeasurer oluşturun ve ölçüm aracıyla drawText adlı kişiyi arayın:

val textMeasurer = rememberTextMeasurer()

Canvas(modifier = Modifier.fillMaxSize()) {
    drawText(textMeasurer, "Hello")
}

Canvas'ta çizilen Merhaba yazısını gösteren resim
Şekil 8. Kanvas'ta metin çizme.

Metni ölçün

Metin çizimi, diğer çizim komutlarından biraz farklı şekilde çalışır. Normalde çizim komutuna şeklin/resmin çizileceği boyut (genişlik ve yükseklik) değerini verin. Metinlerde, yazı tipi boyutu, yazı tipi, ligatür ve harf aralığı gibi oluşturulan metnin boyutunu kontrol eden birkaç parametre vardır.

Oluştur'da, ölçülen öğelere erişmek için TextMeasurer metnin boyutunu değiştirebilirsiniz. Metnin arkasına bir arka plan çizmek istiyorsanız metnin kapladığı alanın boyutunu öğrenmek için ölçülen bilgileri kullanabilirsiniz:

val textMeasurer = rememberTextMeasurer()

Spacer(
    modifier = Modifier
        .drawWithCache {
            val measuredText =
                textMeasurer.measure(
                    AnnotatedString(longTextSample),
                    constraints = Constraints.fixedWidth((size.width * 2f / 3f).toInt()),
                    style = TextStyle(fontSize = 18.sp)
                )

            onDrawBehind {
                drawRect(pinkColor, size = measuredText.size.toSize())
                drawText(measuredText)
            }
        }
        .fillMaxSize()
)

Bu kod snippet'i, metinde pembe bir arka plan oluşturur:

Tüm alanın 2⁄3'ünü kaplayan ve arka planı dikdörtgen olan çok satırlı metinler
Şekil 9. Arka plan dikdörtgeni içeren, tüm alanın ⅔'ünü kaplayan çok satırlı metin.

Kısıtlamaları, yazı tipi boyutunu veya ölçülen boyutu etkileyen herhangi bir özelliği ayarlama yeni bir boyut raporlanır. Hem width hem de height için sabit bir boyut ayarlayabilirsiniz. Ardından metin, ayarlanan TextOverflow değerini takip eder. Örneğin, Örneğin, aşağıdaki kodda metin, yüksekliğin 1⁄3'ü ve genişliğinin 1⁄3'ü oranında oluşturulur değerini değiştirir ve TextOverflow değerini TextOverflow.Ellipsis olarak ayarlar:

val textMeasurer = rememberTextMeasurer()

Spacer(
    modifier = Modifier
        .drawWithCache {
            val measuredText =
                textMeasurer.measure(
                    AnnotatedString(longTextSample),
                    constraints = Constraints.fixed(
                        width = (size.width / 3f).toInt(),
                        height = (size.height / 3f).toInt()
                    ),
                    overflow = TextOverflow.Ellipsis,
                    style = TextStyle(fontSize = 18.sp)
                )

            onDrawBehind {
                drawRect(pinkColor, size = measuredText.size.toSize())
                drawText(measuredText)
            }
        }
        .fillMaxSize()
)

Metin artık kısıtlamalar içinde üç nokta ile çizilir:

Pembe arka plan üzerine çizilmiş metin. Metni kesen üç nokta var.
Şekil 10. Metin ölçümünde sabit kısıtlamalarla TextOverflow.Ellipsis.

Resim çizme

DrawScope ile ImageBitmap çizmek için ImageBitmap.imageResource() kullanarak resmi yükleyin ve ardından drawImage'i çağırın:

val dogImage = ImageBitmap.imageResource(id = R.drawable.dog)

Canvas(modifier = Modifier.fillMaxSize(), onDraw = {
    drawImage(dogImage)
})

Tuval üzerine çizilmiş bir köpeğin resmi
Şekil 11. Tuval üzerinde ImageBitmap çiziliyor.

Temel şekiller çizme

DrawScope üzerinde çok sayıda şekil çizim işlevi var. Şekil çizmek için birini kullanın şu gibi önceden tanımlanmış çizim işlevlerinin bir kısmıdır: drawCircle:

val purpleColor = Color(0xFFBA68C8)
Canvas(
    modifier = Modifier
        .fillMaxSize()
        .padding(16.dp),
    onDraw = {
        drawCircle(purpleColor)
    }
)

API

Çıkış

drawCircle()

daire çizme

drawRect()

dikdörtgen çizin

drawRoundedRect()

yuvarlak dikdörtgen çiz

drawLine()

çizgi çizme

drawOval()

oval çiz

drawArc()

yay çizme

drawPoints()

çizim noktaları

Yol çizin

Yol, uygulandığında bir çizimle sonuçlanan bir dizi matematiksel talimattır. DrawScope, DrawScope.drawPath() yöntemini kullanarak bir yol çizebilir.

Örneğin, bir üçgen çizmek istediğinizi varsayalım. Birlikte yol oluşturmak için fonksiyonlarını (ör. lineTo() ve moveTo()) kullanabilirsiniz. Ardından, üçgen oluşturmak için yeni oluşturulan bu yolu kullanarak drawPath() işlevini çağırın.

Spacer(
    modifier = Modifier
        .drawWithCache {
            val path = Path()
            path.moveTo(0f, 0f)
            path.lineTo(size.width / 2f, size.height / 2f)
            path.lineTo(size.width, 0f)
            path.close()
            onDrawBehind {
                drawPath(path, Color.Magenta, style = Stroke(width = 10f))
            }
        }
        .fillMaxSize()
)

Oluştur'da çizilen ters mor yol üçgeni
Şekil 12. Oluşturma bölümünde Path oluşturma ve çizme

Canvas nesnesine erişim

DrawScope ile Canvas nesnesine doğrudan erişiminiz yoktur. İşlev çağırabileceğiniz Canvas nesnesine erişmek için DrawScope.drawIntoCanvas() kullanabilirsiniz.

Örneğin, eklemek istediğiniz özel bir Drawable tuvale erişebilir ve Drawable#draw() numaralı telefonu, Canvas nesne:

val drawable = ShapeDrawable(OvalShape())
Spacer(
    modifier = Modifier
        .drawWithContent {
            drawIntoCanvas { canvas ->
                drawable.setBounds(0, 0, size.width.toInt(), size.height.toInt())
                drawable.draw(canvas.nativeCanvas)
            }
        }
        .fillMaxSize()
)

Tam boyutta yer kaplayan oval siyah bir ShapeDrawable
Şekil 13. Drawable çizmek için tuvale erişiliyor.

Daha fazla bilgi

Oluşturma'da çizim yapma hakkında daha fazla bilgi için aşağıdaki kaynaklara göz atın: