Grafik değiştiriciler

Oluşturma'da, Canvas bileşenine ek olarak özel içerik çizmenize yardımcı olacak çeşitli faydalı grafiklerModifiers bulunur. Bu değiştiriciler, herhangi bir kompozisyona uygulanabildikleri için kullanışlıdır.

Çizim değiştiricileri

Tüm çizim komutları, Oluşturma'da bir çizim değiştiriciyle yapılır. Oluşturma bölümünde üç ana çizim değiştirici vardır:

Çizim için temel değiştirici drawWithContent'tür. Burada, Composable'ınızın çizim sırasına ve değiştiricide verilen çizim komutlarına karar verebilirsiniz. drawBehind, drawWithContent etrafında uygun bir sarmalayıcıdır ve çizim sırasını, kompozisyonun içeriğinin arkasına ayarlanmıştır. drawWithCache, içinde onDrawBehind veya onDrawWithContent'yi çağırır ve bu sınıflarda oluşturulan nesneleri önbelleğe alma mekanizması sağlar.

Modifier.drawWithContent: Çizim sırasını seçin

Modifier.drawWithContent, DrawScope işlemlerini, birleştirilebilir öğenin içeriğinden önce veya sonra yürütmenize olanak tanır. Daha sonra, derlenebilir öğenin gerçek içeriğini oluşturmak için drawContent işlevini çağırdığınızdan emin olun. Bu değiştiriciyi kullanarak, içeriğinizin özel çizim işlemlerinizden önce mi yoksa sonra mı çizileceğine karar verebilirsiniz.

Örneğin, kullanıcı arayüzünde el feneri anahtar deliği efekti oluşturmak için içeriğinizin üzerine radyal degrade oluşturmak istiyorsanız aşağıdakileri yapabilirsiniz:

var pointerOffset by remember {
    mutableStateOf(Offset(0f, 0f))
}
Column(
    modifier = Modifier
        .fillMaxSize()
        .pointerInput("dragging") {
            detectDragGestures { change, dragAmount ->
                pointerOffset += dragAmount
            }
        }
        .onSizeChanged {
            pointerOffset = Offset(it.width / 2f, it.height / 2f)
        }
        .drawWithContent {
            drawContent()
            // draws a fully black area with a small keyhole at pointerOffset that’ll show part of the UI.
            drawRect(
                Brush.radialGradient(
                    listOf(Color.Transparent, Color.Black),
                    center = pointerOffset,
                    radius = 100.dp.toPx(),
                )
            )
        }
) {
    // Your composables here
}

Şekil 1: El feneri türü bir kullanıcı arayüzü deneyimi oluşturmak için Composable'ın üzerinde kullanılan Modifier.drawWithContent.

Modifier.drawBehind: Bir composable'ın arkasına çizim yapma

Modifier.drawBehind, ekranda çizilen birleştirilebilir içeriğin arkasında DrawScope işlemleri gerçekleştirmenize olanak tanır. Canvas işlevini incelerseniz bunun Modifier.drawBehind işlevinin etrafına yerleştirilmiş kullanışlı bir sarmalayıcı olduğunu fark edebilirsiniz.

Text öğesinin arkasına yuvarlatılmış bir dikdörtgen çizmek için:

Text(
    "Hello Compose!",
    modifier = Modifier
        .drawBehind {
            drawRoundRect(
                Color(0xFFBBAAEE),
                cornerRadius = CornerRadius(10.dp.toPx())
            )
        }
        .padding(4.dp)
)

Aşağıdaki sonucu verir:

Modifier.drawBehind kullanılarak çizilen metin ve arka plan
Şekil 2: Modifier.drawBehind kullanılarak çizilen bir metin ve bir arka plan

Modifier.drawWithCache: Çizim nesnelerini çizme ve önbelleğe alma

Modifier.drawWithCache, içinde oluşturulan nesneleri önbelleğe alır. Nesneler, çizim alanının boyutu aynı olduğu veya okunan durum nesneleri değişmediği sürece önbelleğe alınır. Bu değiştirici, çizim sırasında oluşturulan nesnelerin (ör. Brush, Shader, Path vb.) yeniden atanması gerekmediğinden çizim çağrılarının performansını iyileştirmek için yararlıdır.

Alternatif olarak, değiştiricinin dışında remember kullanarak da nesneleri önbelleğe alabilirsiniz. Ancak besteye her zaman erişemediğiniz için bu her zaman mümkün olmaz. Nesneler yalnızca çizim için kullanılıyorsa drawWithCache kullanmak daha yüksek performans sağlayabilir.

Örneğin, bir Text'un arkasında degrade çizmek için bir Brush oluşturursanız drawWithCache, çizim alanının boyutu değişene kadar Brush nesnesini önbelleğe alır:

Text(
    "Hello Compose!",
    modifier = Modifier
        .drawWithCache {
            val brush = Brush.linearGradient(
                listOf(
                    Color(0xFF9E82F0),
                    Color(0xFF42A5F5)
                )
            )
            onDrawBehind {
                drawRoundRect(
                    brush,
                    cornerRadius = CornerRadius(10.dp.toPx())
                )
            }
        }
)

drawWithCache ile fırça nesnesini önbelleğe alma
Şekil 3: drawWithCache ile Brush nesnesini önbelleğe alma

Grafik değiştiriciler

Modifier.graphicsLayer: Birleştirilebilir öğelere dönüşümler uygulama

Modifier.graphicsLayer, birleştirilebilir çizimin içeriğini çizim katmanı haline getiren bir değiştiricidir. Katmanlar aşağıdakiler gibi birkaç farklı işlev sağlar:

  • Çizim talimatları için yalıtım (RenderNode'a benzer). Bir katmanın parçası olarak yakalanan çizim talimatları, uygulama kodu yeniden yürütülmeden oluşturma hattı tarafından verimli bir şekilde yeniden yayınlanabilir.
  • Bir katmandaki tüm çizim talimatları için geçerli olan dönüşümler.
  • Beste özellikleri için rasterleştirme. Bir katman pikselleştirildiğinde, çizim talimatları uygulanır ve çıkış, ekran dışı bir arabelleğe alınır. Sonraki kareler için bu tür bir arabelleğin birleştirilmesi, talimatları tek tek yürütmekten daha hızlıdır ancak ölçeklendirme veya döndürme gibi dönüştürme işlemleri uygulandığında bir bitmap gibi davranır.

Dönüşümler

Modifier.graphicsLayer, çizim talimatları için yalıtım sağlar. Örneğin, Modifier.graphicsLayer kullanılarak çeşitli dönüşümler uygulanabilir. Bunlar, çizim lambda'sını yeniden yürütmeye gerek kalmadan animasyonlu hale getirilebilir veya değiştirilebilir.

Modifier.graphicsLayer, yalnızca çizim aşamasını etkilediği için birleştirilebilir öğenizin ölçülen boyutunu veya yerleşimini değiştirmez. Bu, kompozisyonunuzun, düzen sınırlarının dışında çizilmesi durumunda diğer öğelerle örtüşebileceği anlamına gelir.

Bu değiştiriciyle aşağıdaki dönüşümler uygulanabilir:

Ölçek - boyutu artır

scaleX ve scaleY, içeriği sırasıyla yatay veya dikey yönde büyütür ya da küçültür. 1.0f değeri, ölçekte değişiklik olmadığını, 0.5f değeri ise boyutun yarısı anlamına gelir.

Image(
    painter = painterResource(id = R.drawable.sunset),
    contentDescription = "Sunset",
    modifier = Modifier
        .graphicsLayer {
            this.scaleX = 1.2f
            this.scaleY = 0.8f
        }
)

Şekil 4: Bir resim bileşimine uygulanan scaleX ve scaleY
Çeviri

translationX ve translationY, graphicsLayer ile değiştirilebilir. translationX, bileşiği sola veya sağa hareket ettirir. translationY, bileşiği yukarı veya aşağı taşır.

Image(
    painter = painterResource(id = R.drawable.sunset),
    contentDescription = "Sunset",
    modifier = Modifier
        .graphicsLayer {
            this.translationX = 100.dp.toPx()
            this.translationY = 10.dp.toPx()
        }
)

Şekil 5: Modifier.graphicsLayer ile Image'e uygulanan translationX ve translationY
Döndürme

rotationX yatay, rotationY dikey ve rotationZ Z ekseninde (standart döndürme) döndürmek için ayarlanır. Bu değer derece cinsinden (0-360) belirtilir.

Image(
    painter = painterResource(id = R.drawable.sunset),
    contentDescription = "Sunset",
    modifier = Modifier
        .graphicsLayer {
            this.rotationX = 90f
            this.rotationY = 275f
            this.rotationZ = 180f
        }
)

Şekil 6: rotationX, rotationY ve rotationZ, Modifier.graphicsLayer tarafından Image üzerinde ayarlanır
Köken

Bir transformOrigin belirtilebilir. Ardından, dönüşümlerin gerçekleştiği nokta olarak kullanılır. Şimdiye kadarki tüm örneklerde, (0.5f, 0.5f) adresindeki TransformOrigin.Center kullanılmıştır. (0f, 0f) noktasında orijini belirtirseniz dönüşümler, birleştirilebilir öğenin sol üst köşesinden başlar.

Orijin noktasını rotationZ dönüşümü ile değiştirirseniz öğenin, bileşimin sol üst kısmında döndüğünü görebilirsiniz:

Image(
    painter = painterResource(id = R.drawable.sunset),
    contentDescription = "Sunset",
    modifier = Modifier
        .graphicsLayer {
            this.transformOrigin = TransformOrigin(0f, 0f)
            this.rotationX = 90f
            this.rotationY = 275f
            this.rotationZ = 180f
        }
)

Şekil 7: TransformOrigin 0f, 0f olarak ayarlandığında uygulanan rotasyon

Klip ve Şekil

Şekil, clip = true olduğunda içeriğin kırpıldığı ana hattı belirtir. Bu örnekte, biri graphicsLayer klip değişkeni, diğeri de pratik sarmalayıcı Modifier.clip olacak şekilde iki farklı klibe sahip iki kutu ayarladık.

Column(modifier = Modifier.padding(16.dp)) {
    Box(
        modifier = Modifier
            .size(200.dp)
            .graphicsLayer {
                clip = true
                shape = CircleShape
            }
            .background(Color(0xFFF06292))
    ) {
        Text(
            "Hello Compose",
            style = TextStyle(color = Color.Black, fontSize = 46.sp),
            modifier = Modifier.align(Alignment.Center)
        )
    }
    Box(
        modifier = Modifier
            .size(200.dp)
            .clip(CircleShape)
            .background(Color(0xFF4DB6AC))
    )
}

İlk kutunun içeriği ("Merhaba Oluştur" yazan metin) daire şekline kırpılır:

Box bileşenine uygulanan klip
Şekil 8: Box composable'a uygulanan klip

Ardından üstteki pembe daireye bir translationY uygularsanız bileşimli öğenin sınırları aynı kalır ancak daire alttaki dairenin altında (ve sınırları dışında) çizilir.

Y ekseni yönünde çeviri uygulanmış ve dış çizgi için kırmızı kenarlıklı klip
Şekil 9: Klip çevrilebilirY ve dış çizgi için kırmızı kenarlık uygulanmıştır

Kompoziti çizildiği bölgeye kırpmak için değiştirici zincirinin başına başka bir Modifier.clip(RectangleShape) ekleyebilirsiniz. İçerik daha sonra orijinal sınırların içinde kalır.

Column(modifier = Modifier.padding(16.dp)) {
    Box(
        modifier = Modifier
            .clip(RectangleShape)
            .size(200.dp)
            .border(2.dp, Color.Black)
            .graphicsLayer {
                clip = true
                shape = CircleShape
                translationY = 50.dp.toPx()
            }
            .background(Color(0xFFF06292))
    ) {
        Text(
            "Hello Compose",
            style = TextStyle(color = Color.Black, fontSize = 46.sp),
            modifier = Modifier.align(Alignment.Center)
        )
    }

    Box(
        modifier = Modifier
            .size(200.dp)
            .clip(RoundedCornerShape(500.dp))
            .background(Color(0xFF4DB6AC))
    )
}

graphicsLayer dönüşümünün üzerine uygulanan kırpma
Şekil 10: graphicsLayer dönüşümünün üzerine uygulanan klip

Alfa

Modifier.graphicsLayer, katmanın tamamı için bir alpha (opaklık) ayarlamak için kullanılabilir. 1.0f tamamen opak ve 0.0f görünmez.

Image(
    painter = painterResource(id = R.drawable.sunset),
    contentDescription = "clock",
    modifier = Modifier
        .graphicsLayer {
            this.alpha = 0.5f
        }
)

Alfa uygulanmış resim
Şekil 11: Alfa uygulanmış resim
bölümüne bakın.CompositingStrategy

Birleştirme stratejisi

Alfa ve şeffaflıkla çalışmak, tek bir alfa değerini değiştirmek kadar basit olmayabilir. Alfa sürümünü değiştirmenin yanı sıra graphicsLayer cihazda CompositingStrategy ayarlama seçeneği de vardır. CompositingStrategy, kompozisyonun içeriğinin ekranda önceden çizilmiş diğer içerikle nasıl birleştirileceğini (bir araya getirileceğini) belirler.

Farklı stratejiler şunlardır:

Otomatik (varsayılan)

Oluşturma stratejisi, graphicsLayer parametrelerinin geri kalanı tarafından belirlenir. Alfa, 1,0f'den küçükse veya bir RenderEffect ayarlanmışsa katmanı ekran dışı bir arabellekte oluşturur. Alfa 1'den azsa içeriği oluşturmak ve ardından bu ekran dışı arabelleği hedefe ilgili alfa ile çizmek için otomatik olarak bir birleştirme katmanı oluşturulur. RenderEffect veya aşırı kaydırma ayarlamak, CompositingStrategy grubundan bağımsız olarak içeriği her zaman ekran dışı bir arabellekte oluşturur.

Ekran dışı

Birleştirilebilir öğenin içeriği, hedefte oluşturulmadan önce her zaman ekran dışı bir dokuya veya bitmap'e rasterleştirilir. Bu, içeriği maskelemek için BlendMode işlemlerini uygulamak ve karmaşık çizim talimatlarını oluşturma performansı için kullanışlıdır.

CompositingStrategy.Offscreen türü, BlendModes ile birlikte kullanılabilir. Aşağıdaki örneğe göz atarak BlendMode.Clear kullanan bir çizim komutu vererek Image composable'ın bazı bölümlerini kaldırmak istediğinizi varsayalım. compositingStrategy öğesini CompositingStrategy.Offscreen olarak ayarlamazsanız BlendMode altındaki tüm içeriklerle etkileşime girer.

Image(
    painter = painterResource(id = R.drawable.dog),
    contentDescription = "Dog",
    contentScale = ContentScale.Crop,
    modifier = Modifier
        .size(120.dp)
        .aspectRatio(1f)
        .background(
            Brush.linearGradient(
                listOf(
                    Color(0xFFC5E1A5),
                    Color(0xFF80DEEA)
                )
            )
        )
        .padding(8.dp)
        .graphicsLayer {
            compositingStrategy = CompositingStrategy.Offscreen
        }
        .drawWithCache {
            val path = Path()
            path.addOval(
                Rect(
                    topLeft = Offset.Zero,
                    bottomRight = Offset(size.width, size.height)
                )
            )
            onDrawWithContent {
                clipPath(path) {
                    // this draws the actual image - if you don't call drawContent, it wont
                    // render anything
                    this@onDrawWithContent.drawContent()
                }
                val dotSize = size.width / 8f
                // Clip a white border for the content
                drawCircle(
                    Color.Black,
                    radius = dotSize,
                    center = Offset(
                        x = size.width - dotSize,
                        y = size.height - dotSize
                    ),
                    blendMode = BlendMode.Clear
                )
                // draw the red circle indication
                drawCircle(
                    Color(0xFFEF5350), radius = dotSize * 0.8f,
                    center = Offset(
                        x = size.width - dotSize,
                        y = size.height - dotSize
                    )
                )
            }
        }
)

CompositingStrategy, Offscreen olarak ayarlanarak komutları yürütmek için ekran dışı bir doku oluşturur (BlendMode yalnızca bu bileşiğin içeriğine uygulanır). Ardından, ekranda zaten oluşturulmuş olan içeriğin üzerine oluşturulur ve önceden çizilmiş içeriği etkilemez.

Uygulama içinde BlendMode.Clear ile daire göstergesi gösteren bir resimde Modifier.drawWithContent
Şekil 12: BlendMode.Clear and CompositingPolicy.Offscreen dahilindeki uygulamanın içinde, daire şeklinde bir işaret gösteren Resim üzerinde Modifier.drawWithContent

CompositingStrategy.Offscreen kullanmadıysanız BlendMode.Clear uygulamanın sonuçları, önceden ayarlanmış olandan bağımsız olarak hedefteki tüm pikselleri temizler ve pencerenin oluşturma arabelleğinin (siyah) görünür kalmasını sağlar. Alfa içeren BlendModes öğelerinin çoğu, ekran dışı arabellek olmadan beklendiği gibi çalışmaz. Kırmızı daire göstergesinin etrafındaki siyah halkayı not edin:

BlendMode.Clear ve CompositingStrategy ayarlanmamışken bir daire göstergesi gösteren bir resimde Modifier.drawWithContent
Şekil 13: BlendMode.Clear ve CompositingStrategy ayarlanmamışken bir daire göstergesi gösteren bir resimde Modifier.drawWithContent

Bunu biraz daha açıklamak gerekirse: Uygulamanın şeffaf bir pencere arka planı varsa ve CompositingStrategy.Offscreen'ü kullanmadıysanız BlendMode, uygulamanın tamamıyla etkileşim kurar. Bu örnekte gösterildiği gibi, uygulamayı veya altındaki duvar kağıdını göstermek için tüm pikselleri temizler:

CompositingPolicy ayarlanmamış ve BlendMode.Clear adlı uygulama, saydam pencere arka planına sahip bir uygulamayla kullanılıyor. Pembe duvar kağıdı, kırmızı durum çemberinin etrafındaki alanda gösterilir.
Şekil 14: CompositingStrategy ayarlanmamış ve yarı saydam pencere arka planına sahip bir uygulamada BlendMode.Clear kullanılıyor. Kırmızı durum çemberinin etrafındaki alanda pembe duvar kağıdının nasıl gösterildiğine dikkat edin.

CompositingStrategy.Offscreen kullanıldığında, çizim alanının boyutunda bir ekran dışı doku oluşturulup ekranda yeniden oluşturulduğunu belirtmek gerekir. Bu stratejiyle yapılan çizim komutları varsayılan olarak bu bölgeye kopyalanır. Aşağıdaki kod snippet'inde, ekran dışı dokuları kullanmaya geçişte ortaya çıkan farklılıklar gösterilmektedir:

@Composable
fun CompositingStrategyExamples() {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .wrapContentSize(Alignment.Center)
    ) {
        // Does not clip content even with a graphics layer usage here. By default, graphicsLayer
        // does not allocate + rasterize content into a separate layer but instead is used
        // for isolation. That is draw invalidations made outside of this graphicsLayer will not
        // re-record the drawing instructions in this composable as they have not changed
        Canvas(
            modifier = Modifier
                .graphicsLayer()
                .size(100.dp) // Note size of 100 dp here
                .border(2.dp, color = Color.Blue)
        ) {
            // ... and drawing a size of 200 dp here outside the bounds
            drawRect(color = Color.Magenta, size = Size(200.dp.toPx(), 200.dp.toPx()))
        }

        Spacer(modifier = Modifier.size(300.dp))

        /* Clips content as alpha usage here creates an offscreen buffer to rasterize content
        into first then draws to the original destination */
        Canvas(
            modifier = Modifier
                // force to an offscreen buffer
                .graphicsLayer(compositingStrategy = CompositingStrategy.Offscreen)
                .size(100.dp) // Note size of 100 dp here
                .border(2.dp, color = Color.Blue)
        ) {
            /* ... and drawing a size of 200 dp. However, because of the CompositingStrategy.Offscreen usage above, the
            content gets clipped */
            drawRect(color = Color.Red, size = Size(200.dp.toPx(), 200.dp.toPx()))
        }
    }
}

Compositingstrateji.Auto ve CompositingPolicy.Offscreen, otomatik oynatmanın mümkün olmadığı bölgeye yönelik ekran dışı klipler
Şekil 15: CompositingStrategy.Auto ve CompositingStrategy.Offscreen: Otomatik özelliğin kullanılamadığı bölgelerde ekran dışı klipler
ModulateAlpha

Bu kompozisyon stratejisi, graphicsLayer içinde kaydedilen her çizim talimatının alfa değerini modüle eder. RenderEffect ayarlanmadığı sürece 1,0f'ın altındaki alfa için ekran dışı bir arabellek oluşturmaz.Bu nedenle, alfa oluşturma için daha verimli olabilir. Ancak çakışan içerikler için farklı sonuçlar sağlayabilir. İçeriğin örtüşmediği önceden bilinen kullanım alanları için bu yöntem, alfa değerleri 1'den küçük olan CompositingStrategy.Auto'ten daha iyi performans sağlayabilir.

Farklı kompozisyon stratejilerine örnek olarak aşağıdakileri verebiliriz: Birleştirilebilir öğelerin farklı bölümlerine farklı alfa değerleri uygulama ve Modulate stratejisi uygulama:

@Preview
@Composable
fun CompositingStrategy_ModulateAlpha() {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(32.dp)
    ) {
        // Base drawing, no alpha applied
        Canvas(
            modifier = Modifier.size(200.dp)
        ) {
            drawSquares()
        }

        Spacer(modifier = Modifier.size(36.dp))

        // Alpha 0.5f applied to whole composable
        Canvas(
            modifier = Modifier
                .size(200.dp)
                .graphicsLayer {
                    alpha = 0.5f
                }
        ) {
            drawSquares()
        }
        Spacer(modifier = Modifier.size(36.dp))

        // 0.75f alpha applied to each draw call when using ModulateAlpha
        Canvas(
            modifier = Modifier
                .size(200.dp)
                .graphicsLayer {
                    compositingStrategy = CompositingStrategy.ModulateAlpha
                    alpha = 0.75f
                }
        ) {
            drawSquares()
        }
    }
}

private fun DrawScope.drawSquares() {

    val size = Size(100.dp.toPx(), 100.dp.toPx())
    drawRect(color = Red, size = size)
    drawRect(
        color = Purple, size = size,
        topLeft = Offset(size.width / 4f, size.height / 4f)
    )
    drawRect(
        color = Yellow, size = size,
        topLeft = Offset(size.width / 4f * 2f, size.height / 4f * 2f)
    )
}

val Purple = Color(0xFF7E57C2)
val Yellow = Color(0xFFFFCA28)
val Red = Color(0xFFEF5350)

ModlateAlpha, alfa kümesini her çizim komutuna uygular
Şekil 16: ModulateAlpha, ayarlanan alfa değerini her bir çizim komutuna uygular

Bir bileşiğin içeriğini bitmap'e yazma

Bu işlevin yaygın bir kullanım alanı, bir bileşenden Bitmap oluşturmaktır. Kompozitinizin içeriğini bir Bitmap'e kopyalamak için rememberGraphicsLayer() kullanarak bir GraphicsLayer oluşturun.

drawWithContent() ve graphicsLayer.record{} tuşlarını kullanarak çizim komutlarını yeni katmana yönlendirin. Ardından, drawLayer seçeneğini kullanarak katmanı görünür kanvasta çizin:

val coroutineScope = rememberCoroutineScope()
val graphicsLayer = rememberGraphicsLayer()
Box(
    modifier = Modifier
        .drawWithContent {
            // call record to capture the content in the graphics layer
            graphicsLayer.record {
                // draw the contents of the composable into the graphics layer
                this@drawWithContent.drawContent()
            }
            // draw the graphics layer on the visible canvas
            drawLayer(graphicsLayer)
        }
        .clickable {
            coroutineScope.launch {
                val bitmap = graphicsLayer.toImageBitmap()
                // do something with the newly acquired bitmap
            }
        }
        .background(Color.White)
) {
    Text("Hello Android", fontSize = 26.sp)
}

Bit eşlemesini diske kaydedip paylaşabilirsiniz. Daha fazla bilgi için tam örnek snippet'ine bakın. Diske kaydetmeyi denemeden önce cihazdaki izinleri kontrol edin.

Özel çizim değiştirici

Kendi özel değiştiricinizi oluşturmak için DrawModifier arayüzünü uygulayın. Bu, Modifier.drawWithContent() kullanırken gösterilenle aynı olan bir ContentDrawScope'ye erişim sağlar. Ardından, kodu temizlemek ve kullanışlı sarmalayıcılar sağlamak için yaygın çizim işlemlerini özel çizim değiştiricilerine ayıklayabilirsiniz. Örneğin, Modifier.background() kullanışlı bir DrawModifier'dur.

Örneğin, içeriği dikey olarak çeviren bir Modifier uygulamak istiyorsanız aşağıdaki gibi bir sürüm oluşturabilirsiniz:

class FlippedModifier : DrawModifier {
    override fun ContentDrawScope.draw() {
        scale(1f, -1f) {
            this@draw.drawContent()
        }
    }
}

fun Modifier.flipped() = this.then(FlippedModifier())

Ardından, Text tarihinde uygulanan ters çevrilmiş bu değiştiriciyi kullanın:

Text(
    "Hello Compose!",
    modifier = Modifier
        .flipped()
)

Metinde Özel Ters Çevirme Değiştirici
Şekil 17: Metin Üzerinde Özel Çevrilmiş Değiştirici

Ek kaynaklar

graphicsLayer ve özel çizimin kullanıldığı daha fazla örnek için aşağıdaki kaynaklara göz atın: