Grafik değiştiriciler

Compose, Canvas composable'ın yanı sıra özel içerik çizmeye yardımcı olan birkaç kullanışlı grafik de Modifiers içerir. Bu değiştiriciler, her composable'a uygulanabileceğinden faydalıdır.

Çizim değiştiricileri

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

Çizimin temel değiştiricisi drawWithContent şeklindedir. Burada, Özelleştirilebilir'in çizim sırasına ve değiştirici içinde verilen çizim komutlarına karar verebilirsiniz. drawBehind, çizim sırası composable'ın içeriğinin arkasına ayarlandığı drawWithContent için kullanışlı bir sarmalayıcıdır. drawWithCache, bunun içinde onDrawBehind veya onDrawWithContent yöntemini çağırır ve bunların içinde oluşturulan nesneleri önbelleğe almak için bir mekanizma sağlar.

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

Modifier.drawWithContent, composable'ın içeriğinden önce veya sonra DrawScope işlemleri yapmanıza olanak tanır. composable'ın gerçek içeriğini oluşturmak için drawContent yöntemini çağırdığınızdan emin olun. Bu değiştiriciyle, içeriğinizin özel çizim işlemlerinizden önce veya sonra çizilmesini istiyorsanız işlemlerin sırasına karar verebilirsiniz.

Örneğin, kullanıcı arayüzünde el feneri anahtar deliği efekti oluşturmak için içeriğinizin üzerinde dairesel bir renk geçişi 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ünde bir kullanıcı arayüzü deneyimi oluşturmak için Composable'ın üzerine kullanılan Modifier.drawWithContent.

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

Modifier.drawBehind, ekranda çizilen composable içeriklerin arkasında DrawScope işlemleri gerçekleştirmenizi sağlar. Canvas uygulamasına göz atarsanız bunun yalnızca Modifier.drawBehind etiketi için uygun bir sarmalayıcı olduğunu fark edebilirsiniz.

Text öğesinin arkasına yuvarlak 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:

Değiştirici.drawBehind kullanılarak çizilmiş bir metin ve bir 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. Çizim alanının boyutu aynı olduğu veya okunan durum nesneleri değişmediği sürece nesneler önbelleğe alınır. Bu değiştirici, çizim sırasında oluşturulan nesnelerin (Brush, Shader, Path vb.) yeniden tahsis edilmesi ihtiyacını ortadan kaldırdığı için çizim çağrılarının performansını iyileştirmek açısından faydalıdır.

Alternatif olarak, değiştiricinin dışında, remember öğesini 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 işlevinin kullanılması daha etkili olabilir.

Örneğin, bir Text öğesinin arkasına bir renk geçişi çizmek için Brush oluşturursanız drawWithCache kullanıldığında, çizim alanının boyutu değişene kadar Brush nesnesi önbelleğe alınır:

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

Brush nesnesinidrawWithCache ile önbelleğe alma
Şekil 3: Trafiğe nesnesinidrawWithCache ile önbelleğe alma

Grafik değiştiriciler

Modifier.graphicsLayer: Dönüşüm işlemlerini composable'lara uygulama

Modifier.graphicsLayer, composable çizim içeriğini bir çizim katmanına dönüştüren bir değiştiricidir. Katman, aşağıdakiler gibi birkaç farklı işlev sağlar:

  • Çizim talimatları için izolasyon (RenderNode benzeri). Bir katmanın bir parçası olarak yakalanan çizim talimatları, oluşturma ardışık düzeni tarafından uygulama kodu yeniden yürütülmeden etkili bir şekilde yeniden verilebilir.
  • Bir katmanda yer alan tüm çizim talimatlarına uygulanan dönüşümler.
  • Kompozisyon özellikleri için pikselleştirme. Bir katman pikselleştirildiğinde, çizim talimatları uygulanır ve çıkış, ekran dışı bir arabelleğe alınır. Böyle bir arabelleği sonraki kareler için birleştirmek, tek tek talimatları uygulamaktan daha hızlıdır ancak ölçeklendirme veya döndürme gibi dönüşümler uygulandığında bit eşlem olarak 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 lambdasını yeniden yürütmeye gerek kalmadan canlandırılabilir veya değiştirilebilir.

Modifier.graphicsLayer, yalnızca çizim aşamasını etkilediği için composable'ınızın ölçülen boyutunu veya yerleşimini değiştirmez. Bu, composable'ınızın düzen sınırlarının dışında çizim yapması halinde başkalarıyla çakışabileceğ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: composable'a uygulanan scaleX ve scaleY
Çeviri

translationX ve translationY, graphicsLayer ile değiştirilebilir. translationX, composable'ı sola veya sağa taşır. translationY, composable'ı 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: Değiştirici.graphicslayer ile resme uygulanan çeviriX ve çeviriY
Döndürme

Yatay döndürmek için rotationX simgesini, dikey olarak döndürmek için rotationY değerini ve Z ekseninde döndürmek için rotationZ simgesini (standart döndürme) ayarlayın. Bu değer derece (0-360) cinsinden belirtilir.

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

Şekil 6: Değiştirici.graphicsKatman tarafından Resim üzerinde ayarlanan rotasyonX, döndürmeY ve döndürmeZ
Kalkış noktası

transformOrigin belirtilebilir. Daha sonra 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ıldı. Kaynağı (0f, 0f) adresinde belirtirseniz dönüşümler, composable'ın sol üst köşesinden başlar.

Kaynağı rotationZ dönüşümüyle değiştirirseniz öğenin composable'ın sol üst köşesinde 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 döndürme

Klip ve şekil

Şekil, clip = true sırasında içeriğin klibinin ana hatlarını 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:

Klip, Box'taki composable'a uygulandı
Şekil 8: Box composable'a uygulanan klip

Daha sonra, üstteki pembe daireye bir translationY değeri uygularsanız Özelleştirilebilir'in sınırlarının aynı olduğunu ancak dairenin alt dairenin altına (ve sınırlarının dışına) çizildiğini görürsünüz.

Klip, çeviriY ve dış çizgi için kırmızı kenarlık uygulandı
Şekil 9: Klip, çevrilebilirY ve dış çizgi için kırmızı kenarlık uygulanmıştır

composable'ı çizildiği bölgeye göre klip oluşturmak için değiştirici zincirinin başına başka bir Modifier.clip(RectangleShape) ekleyebilirsiniz. Bu durumda içerik 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))
    )
}

Grafik Katmanı dönüşümünün üzerine klip uygulandı
Şekil 10: Grafik katmanı dönüşümünün üzerine klip uygulandı

Alfa

Modifier.graphicsLayer, tüm katman için alpha (opaklık) değeri ayarlamak amacıyla 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
1 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 kolay olmayabilir. Alfa sürümünü değiştirmenin yanı sıra graphicsLayer cihazda CompositingStrategy ayarlama seçeneği de vardır. CompositingStrategy, composable'ın içeriğinin ekranda çizilmiş diğer içerikle nasıl birleştirileceğini (birleştirileceğini) belirler.

Farklı stratejiler şunlardır:

Otomatik (varsayılan)

Birleştirme stratejisi, diğer graphicsLayer parametreleri tarafından belirlenir. Alfa, 1,0f'den küçükse veya bir RenderEffect ayarlanmışsa katmanı ekran dışı bir arabellekte oluşturur. Alfa değeri 1f'den düşük olduğunda, içeriğin oluşturulması için otomatik olarak bir birleştirme katmanı oluşturulur ve ardından bu ekran dışı arabelleği ilgili alfa sürümüyle hedefe çizeriz. 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ışı

composable'ın içeriği, hedef olarak oluşturulmadan önce her zaman ekran dışı bir dokuya veya bit eşlem olarak pikselleştirilir. Bu, BlendMode işlemlerini içeriği maskelemek için uygulamak ve karmaşık çizim talimatı gruplarını oluştururken performansı artırmak açısından faydalıdır.

BlendModes, CompositingStrategy.Offscreen kullanımına örnek olarak verilebilir. 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 ayarlandığında komutların yürütüleceği bir ekran dışı doku oluşturur (BlendMode öğesini yalnızca bu composable'ın içeriklerine uygular). Daha sonra, çizilmiş içeriği etkilemeden, resmi ekranda oluşturulan içeriğin üzerinde oluşturur.

Daire şeklinde bir gösterimin gösterildiği ve BlendMode.Clear uygulamasının içinde bulunan Değiştirici.drawWithContent
Şekil 12: BlendMode.Clear and CompositingPolicy.Offscreen uygulama içinde dairesel gösterimle birlikte, resimde Değiştirici.drawWithContent

CompositingStrategy.Offscreen kullanmadıysanız BlendMode.Clear uygulanmanın sonuçları, önceden ayarlananlara bakılmaksızın hedefteki tüm pikselleri temizler ve pencerenin oluşturma arabelleğini (siyah) görünür bırakır. 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 halkaya dikkat edin:

Bir resimde BlendMode.Clear ve Compositingstratejisi yok olarak daire şeklinde bir işaret gösteren Modifier.drawWithContent
Şekil 13: Resimde BlendMode.Clear ve CompositingPolicy ayarlı olmayan daire göstergesi gösteren Modifier.drawWithContent

Bunu biraz daha iyi anlamak gerekirse: Uygulama yarı saydam bir pencere arka planına sahipse ve CompositingStrategy.Offscreen özelliğini kullanmadıysanız BlendMode tüm uygulamayla etkileşim kurar. Aşağıdaki örnekte olduğu gibi, uygulamanın veya duvar kağıdının altında görünmesi için tüm pikseller temizlenir:

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 dairesinin çevresinde gösterilir.
Şekil 14: Compositingstratejisi ayarlanmamış ve BlendMode.Clear'ı yarı saydam pencere arka planına sahip bir uygulamayla kullanma. Pembe duvar kağıdının, kırmızı durum dairesinin çevresinde nasıl gösterildiğine dikkat edin.

CompositingStrategy.Offscreen kullanıldığında, çizim alanının boyutunda olan bir ekran dışı dokunun oluşturulduğunu ve tekrar ekranda 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 görülen 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 Compositingstratejisi.Offscreen, otomatik oynatmanın mümkün olmadığı bölgeye yönelik ekran dışı klipler
Şekil 15: Compositingstrateji.Auto ve Compositingstratejileri.Kapalı ekran: Otomatik olmayan, bölgeye özgü ekran dışı klipler
ModulateAlpha

Bu beste stratejisi, graphicsLayer içinde kaydedilen her çizim talimatı için alfa modunu değiştirir. RenderEffect ayarlanmadığı sürece alfa sürümü için 1,0f'nin altında ekran dışı arabellek oluşturmaz.Bu nedenle, alfa oluşturma için daha verimli olabilir. Ancak çakışan içerikler için farklı sonuçlar verebilir. İçeriğin çakışmadığının önceden bilindiği kullanım alanlarında bu, alfa değerlerinin 1'den düşük olduğu CompositingStrategy.Auto ürününden daha iyi performans sağlayabilir.

Farklı beste stratejilerine bir başka örnek aşağıda verilmiştir: composable'ların farklı bölümlerine farklı alfalar uygulama ve bir Modulate stratejisi uygulama:

@Preview
@Composable
fun CompositingStratgey_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: ModlateAlpha, alfa grubunu her bir çizim komutuna uygular

Bir composable'ın içeriğini bit eşlem olarak yazma

Yaygın kullanım alanlarından biri, bir composable'dan Bitmap oluşturmaktır. composable'ınızın içeriğini Bitmap öğesine kopyalamak için rememberGraphicsLayer() kullanarak bir GraphicsLayer oluşturun.

Çizim komutlarını drawWithContent() ve graphicsLayer.record{} tuşlarını kullanarak yeni katmana yönlendirin. Ardından, drawLayer komutunu kullanarak katmanı görünür tuvalde ç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şlemi diske kaydedebilir ve paylaşabilirsiniz. Daha fazla bilgi için tam örnek snippet'e 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 sayede, Modifier.drawWithContent() kullanılırken gösterilenle aynı olan ContentDrawScope öğesine erişebilirsiniz. Ardından, kodu temizlemek ve kullanışlı sarmalayıcılar sağlamak için yaygın çizim işlemlerini özel çizim değiştiricilerine çıkarabilirsiniz. Örneğin, Modifier.background() kullanımı kolaydır DrawModifier.

Ö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 Çevrilmiş 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: