Compose'daki Brush
, ekranda bir şeyin nasıl çizildiğini açıklar: Çizim alanında (ör. daire, kare, yol) çizilen renkleri belirler. Çizim için kullanışlı olan birkaç yerleşik fırça vardır. Örneğin, LinearGradient
, RadialGradient
veya düz bir SolidColor
fırça.
Fırçalar, çizilen içeriğe boyama stilini uygulamak için Modifier.background()
, TextStyle
veya DrawScope
çizim çağrılarıyla kullanılabilir.
Örneğin, yatay gradyan fırça, DrawScope
içinde daire çizmek için kullanılabilir:
val brush = Brush.horizontalGradient(listOf(Color.Red, Color.Blue)) Canvas( modifier = Modifier.size(200.dp), onDraw = { drawCircle(brush) } )

Gradyan fırçalar
Farklı gradyan efektleri elde etmek için kullanılabilecek birçok yerleşik gradyan fırçası vardır. Bu fırçalar, gradyan oluşturmak istediğiniz renklerin listesini belirtmenize olanak tanır.
Kullanılabilir gradyan fırçaların listesi ve ilgili çıkış:
Gradyan Fırça Türü | Çıkış |
---|---|
Brush.horizontalGradient(colorList) |
![]() |
Brush.linearGradient(colorList) |
![]() |
Brush.verticalGradient(colorList) |
![]() |
Brush.sweepGradient(colorList)
Not: Renkler arasında sorunsuz bir geçiş elde etmek için son rengi başlangıç rengi olarak ayarlayın. |
![]() |
Brush.radialGradient(colorList) |
![]() |
colorStops
ile renk dağılımını değiştirme
Renklerin gradyende nasıl görüneceğini özelleştirmek için her bir renk için colorStops
değerini değiştirebilirsiniz. colorStops
, 0 ile 1 arasında bir kesir olarak belirtilmelidir. 1'den büyük değerler, bu renklerin gradyanın bir parçası olarak oluşturulmamasına neden olur.
Renk duraklarını, bir rengin daha az veya daha çok olması gibi farklı miktarlarda olacak şekilde yapılandırabilirsiniz:
val colorStops = arrayOf( 0.0f to Color.Yellow, 0.2f to Color.Red, 1f to Color.Blue ) Box( modifier = Modifier .requiredSize(200.dp) .background(Brush.horizontalGradient(colorStops = colorStops)) )
Renkler, colorStop
çiftinde tanımlandığı gibi sağlanan ofsette dağıtılır. Kırmızı ve maviye kıyasla daha az sarı renk bulunur.

TileMode
ile bir kalıbı tekrarlama
Her gradyan fırçaya TileMode
ekleyebilirsiniz. Gradyan için başlangıç ve bitiş belirlemediyseniz TileMode
simgesini fark etmeyebilirsiniz. Bu durumda, varsayılan olarak tüm alan doldurulur. TileMode
, yalnızca alanın boyutu fırça boyutundan büyükse gradyanı döşer.
endX
değeri 50.dp
, boyut değeri ise 200.dp
olarak ayarlandığından aşağıdaki kod, gradyan desenini 4 kez tekrarlar:
val listColors = listOf(Color.Yellow, Color.Red, Color.Blue) val tileSize = with(LocalDensity.current) { 50.dp.toPx() } Box( modifier = Modifier .requiredSize(200.dp) .background( Brush.horizontalGradient( listColors, endX = tileSize, tileMode = TileMode.Repeated ) ) )
Aşağıdaki tabloda, farklı Döşeme Modlarının yukarıdaki HorizontalGradient
örneğinde ne yaptığı ayrıntılı olarak açıklanmaktadır:
TileMode | Çıkış |
---|---|
TileMode.Repeated : Kenar, son renkten ilk renge doğru tekrarlanır. |
![]() |
TileMode.Mirror : Kenar, son renkten ilk renge doğru yansıtılır. |
![]() |
TileMode.Clamp : Kenar, son renge sabitlenir. Ardından, bölgenin geri kalanında en yakın rengi boyar. |
![]() |
TileMode.Decal : Yalnızca sınırlar boyutunda oluşturun. TileMode.Decal , orijinal sınırların dışındaki içeriği örneklemek için şeffaf siyahı kullanırken TileMode.Clamp , kenar rengini örnekler. |
![]() |
TileMode
, diğer yönlü gradyanlar için de benzer şekilde çalışır. Tek fark, tekrarın gerçekleştiği yöndür.
Fırça boyutunu değiştirme
Fırçanızın çizileceği alanın boyutunu biliyorsanız endX
bölümünde yukarıda gördüğümüz gibi döşemeyi TileMode
olarak ayarlayabilirsiniz. DrawScope
içindeyseniz alanın boyutunu almak için size
özelliğini kullanabilirsiniz.
Çizim alanınızın boyutunu bilmiyorsanız (örneğin, Brush
metne atanmışsa) Shader
öğesini genişletebilir ve createShader
işlevinde çizim alanının boyutunu kullanabilirsiniz.
Bu örnekte, deseni 4 kez tekrarlamak için boyutu 4'e bölün:
val listColors = listOf(Color.Yellow, Color.Red, Color.Blue) val customBrush = remember { object : ShaderBrush() { override fun createShader(size: Size): Shader { return LinearGradientShader( colors = listColors, from = Offset.Zero, to = Offset(size.width / 4f, 0f), tileMode = TileMode.Mirror ) } } } Box( modifier = Modifier .requiredSize(200.dp) .background(customBrush) )

Dairesel renk geçişleri gibi diğer renk geçişlerinin fırça boyutunu da değiştirebilirsiniz. Boyut ve merkez belirtmezseniz gradyan, DrawScope
öğesinin tüm sınırlarını kaplar ve dairesel gradyanın merkezi, DrawScope
sınırlarının merkezine ayarlanır. Bu durumda, radyal gradyanın merkezi, daha küçük boyutun (genişlik veya yükseklik) merkezi olarak görünür:
Box( modifier = Modifier .fillMaxSize() .background( Brush.radialGradient( listOf(Color(0xFF2be4dc), Color(0xFF243484)) ) ) )

Radyal gradyan, yarıçap boyutu maksimum boyuta ayarlanacak şekilde değiştirildiğinde daha iyi bir radyal gradyan efekti oluşturduğunu görebilirsiniz:
val largeRadialGradient = object : ShaderBrush() { override fun createShader(size: Size): Shader { val biggerDimension = maxOf(size.height, size.width) return RadialGradientShader( colors = listOf(Color(0xFF2be4dc), Color(0xFF243484)), center = size.center, radius = biggerDimension / 2f, colorStops = listOf(0f, 0.95f) ) } } Box( modifier = Modifier .fillMaxSize() .background(largeRadialGradient) )

Gölgelendiricinin oluşturulmasına aktarılan gerçek boyutun, çağrıldığı yere göre belirlendiğini belirtmekte fayda vardır. Varsayılan olarak, Brush
boyutu Brush
'nın son oluşturulmasından farklıysa veya gölgelendiricinin oluşturulmasında kullanılan bir durum nesnesi değişmişse Brush
, Shader
'yi dahili olarak yeniden ayırır.
Aşağıdaki kod, çizim alanının boyutu değiştikçe gölgelendiriciyi üç farklı boyutta oluşturur:
val colorStops = arrayOf( 0.0f to Color.Yellow, 0.2f to Color.Red, 1f to Color.Blue ) val brush = Brush.horizontalGradient(colorStops = colorStops) Box( modifier = Modifier .requiredSize(200.dp) .drawBehind { drawRect(brush = brush) // will allocate a shader to occupy the 200 x 200 dp drawing area inset(10f) { /* Will allocate a shader to occupy the 180 x 180 dp drawing area as the inset scope reduces the drawing area by 10 pixels on the left, top, right, bottom sides */ drawRect(brush = brush) inset(5f) { /* will allocate a shader to occupy the 170 x 170 dp drawing area as the inset scope reduces the drawing area by 5 pixels on the left, top, right, bottom sides */ drawRect(brush = brush) } } } )
Resmi fırça olarak kullanma
ImageBitmap'i Brush
olarak kullanmak için resmi ImageBitmap
olarak yükleyin ve ImageShader
fırçası oluşturun:
val imageBrush = ShaderBrush(ImageShader(ImageBitmap.imageResource(id = R.drawable.dog))) // Use ImageShader Brush with background Box( modifier = Modifier .requiredSize(200.dp) .background(imageBrush) ) // Use ImageShader Brush with TextStyle Text( text = "Hello Android!", style = TextStyle( brush = imageBrush, fontWeight = FontWeight.ExtraBold, fontSize = 36.sp ) ) // Use ImageShader Brush with DrawScope#drawCircle() Canvas(onDraw = { drawCircle(imageBrush) }, modifier = Modifier.size(200.dp))
Fırça, birkaç farklı çizim türüne uygulanır: arka plan, metin ve tuval. Bu işlem aşağıdaki çıkışı verir:

Metnin artık metin piksellerini boyamak için ImageBitmap
kullanılarak da oluşturulduğunu unutmayın.
Gelişmiş örnek: Özel fırça
AGSL RuntimeShader
fırçası
AGSL, GLSL Shader özelliklerinin bir alt kümesini sunar. Gölgelendiriciler AGSL'de yazılabilir ve Compose'da fırçayla kullanılabilir.
Shader fırçası oluşturmak için önce Shader'ı AGSL shader dizesi olarak tanımlayın:
@Language("AGSL") val CUSTOM_SHADER = """ uniform float2 resolution; layout(color) uniform half4 color; layout(color) uniform half4 color2; half4 main(in float2 fragCoord) { float2 uv = fragCoord/resolution.xy; float mixValue = distance(uv, vec2(0, 1)); return mix(color, color2, mixValue); } """.trimIndent()
Yukarıdaki gölgelendirici, iki giriş rengi alır, çizim alanının sol alt kısmından (vec2(0, 1)
) olan mesafeyi hesaplar ve mesafeye göre iki renk arasında mix
işlemi yapar. Bu işlem, renk geçişi efekti oluşturur.
Ardından, gölgelendirici fırçayı oluşturun ve resolution
için tek tip değerleri ayarlayın. Bu değerler, çizim alanının boyutu ile özel gradyanınızda giriş olarak kullanmak istediğiniz color
ve color2
değerleridir:
val Coral = Color(0xFFF3A397) val LightYellow = Color(0xFFF8EE94) @RequiresApi(Build.VERSION_CODES.TIRAMISU) @Composable @Preview fun ShaderBrushExample() { Box( modifier = Modifier .drawWithCache { val shader = RuntimeShader(CUSTOM_SHADER) val shaderBrush = ShaderBrush(shader) shader.setFloatUniform("resolution", size.width, size.height) onDrawBehind { shader.setColorUniform( "color", android.graphics.Color.valueOf( LightYellow.red, LightYellow.green, LightYellow .blue, LightYellow.alpha ) ) shader.setColorUniform( "color2", android.graphics.Color.valueOf( Coral.red, Coral.green, Coral.blue, Coral.alpha ) ) drawRect(shaderBrush) } } .fillMaxWidth() .height(200.dp) ) }
Bu komutu çalıştırdığınızda ekranda aşağıdakiler oluşturulur:

Tamamen matematik tabanlı hesaplamalar olduğundan, gölgelendiricilerle yalnızca gradyanlardan çok daha fazlasını yapabileceğinizi belirtmek isteriz. AGSL hakkında daha fazla bilgi için AGSL dokümanlarına göz atın.
Ek kaynaklar
Oluşturma modunda Fırça'yı kullanmayla ilgili daha fazla örnek için aşağıdaki kaynaklara göz atın:
- Oluşturma modunda fırça ile metin renklendirme animasyonu 🖌️
- Custom Graphics and Layouts in Compose - Android Dev Summit 2022
- JetLagged Sample - RuntimeShader Brush
Sizin için önerilenler
- Not: JavaScript kapalıyken bağlantı metni gösterilir.
- Grafik Değiştiriciler
- Oluşturma'daki grafikler
- Metni biçimlendirme