Banyak aplikasi harus dapat mengontrol dengan akurat apa yang digambar di layar. Hal ini mungkin semudah menempatkan kotak atau lingkaran di layar di tempat yang tepat, atau mungkin pengaturan elemen grafik yang rumit dalam banyak gaya yang berbeda.
Gambar dasar dengan pengubah dan DrawScope
Cara inti untuk menggambar sesuatu yang khusus di Compose adalah dengan pengubah, seperti
Modifier.drawWithContent
,
Modifier.drawBehind
, dan
Modifier.drawWithCache
.
Misalnya, untuk menggambar sesuatu di belakang composable, Anda dapat menggunakan
pengubah drawBehind
untuk mulai menjalankan perintah gambar:
Spacer( modifier = Modifier .fillMaxSize() .drawBehind { // this = DrawScope } )
Jika hanya memerlukan composable yang menggambar, Anda dapat menggunakan composable Canvas
. Composable Canvas
adalah
wrapper yang praktis di sekitar Modifier.drawBehind
. Anda menempatkan Canvas
di
tata letak dengan cara yang sama seperti elemen UI Compose lainnya. Dalam
Canvas
, Anda dapat menggambar elemen dengan kontrol gaya dan lokasinya yang akurat.
Semua pengubah gambar mengekspos DrawScope
, cakupan lingkungan gambar
yang mempertahankan statusnya sendiri. Ini memungkinkan Anda menyetel parameter untuk sekelompok
elemen grafik. DrawScope
menyediakan beberapa kolom yang berguna, seperti size
,
objek Size
yang menentukan dimensi DrawScope
saat ini.
Untuk menggambar sesuatu, Anda dapat menggunakan salah satu dari berbagai fungsi gambar di DrawScope
. Misalnya,
kode berikut menggambar persegi panjang di pojok kiri atas
layar:
Canvas(modifier = Modifier.fillMaxSize()) { val canvasQuadrantSize = size / 2F drawRect( color = Color.Magenta, size = canvasQuadrantSize ) }
![Persegi panjang merah muda digambar dengan latar belakang putih yang menempati seperempat layar](https://developer.android.com/static/develop/ui/compose/images/graphics/introduction/compose_graphics_draw_rect.png?authuser=19&hl=id)
Untuk mempelajari lebih lanjut berbagai pengubah gambar, lihat dokumentasi Pengubah Grafik.
Sistem koordinat
Untuk menggambar sesuatu di layar, Anda perlu mengetahui offset (x
dan y
) dan ukuran
item Anda. Dengan banyak metode gambar di DrawScope
, posisi dan ukuran
diberikan oleh parameter value default. Parameter default biasanya memosisikan item di titik [0, 0]
pada kanvas dan menyediakan size
default yang mengisi seluruh area gambar, seperti dalam contoh di atas - Anda dapat melihat kotak persegi panjang berada di posisi kiri atas. Untuk menyesuaikan ukuran dan posisi
item, Anda perlu memahami sistem koordinat di Compose.
Origin sistem koordinat ([0,0]
) berada di piksel paling kiri atas di
area gambar. x
meningkat saat bergerak ke kanan dan y
meningkat saat bergerak
ke bawah.
![Petak yang menunjukkan sistem koordinat yang menampilkan bagian kiri atas [0, 0] dan bagian kanan bawah [lebar, tinggi]](https://developer.android.com/static/develop/ui/compose/images/graphics/introduction/compose_coordinate_system_drawing.png?authuser=19&hl=id)
Misalnya, jika Anda ingin menggambar garis diagonal dari pojok kanan atas
area kanvas ke pojok kiri bawah, Anda dapat menggunakan
fungsi DrawScope.drawLine()
serta dapat menentukan offset awal dan akhir dengan
posisi x dan y yang sesuai:
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 ) }
Transformasi dasar
DrawScope
menawarkan transformasi untuk mengubah lokasi atau cara perintah gambar
dieksekusi.
Skala
Gunakan
DrawScope.scale()
untuk meningkatkan ukuran operasi gambar berdasarkan suatu faktor. Operasi seperti
scale()
berlaku untuk semua operasi gambar dalam lambda yang sesuai. Misalnya,
kode berikut meningkatkan scaleX
10 kali dan scaleY
15
kali:
Canvas(modifier = Modifier.fillMaxSize()) { scale(scaleX = 10f, scaleY = 15f) { drawCircle(Color.Blue, radius = 20.dp.toPx()) } }
![Lingkaran yang diskalakan secara tidak seragam](https://developer.android.com/static/develop/ui/compose/images/graphics/introduction/compose_graphics_canvas_scale.png?authuser=19&hl=id)
Terjemahan
Gunakan
DrawScope.translate()
untuk memindahkan operasi gambar ke atas, bawah, kiri, atau kanan. Misalnya, kode
berikut memindahkan gambar 100 px ke kanan dan 300 px ke atas:
Canvas(modifier = Modifier.fillMaxSize()) { translate(left = 100f, top = -300f) { drawCircle(Color.Blue, radius = 200.dp.toPx()) } }
![Lingkaran yang telah dipindahkan dari tengah](https://developer.android.com/static/develop/ui/compose/images/graphics/introduction/compose_graphics_canvas_translate.png?authuser=19&hl=id)
Rotasi
Gunakan DrawScope.rotate()
untuk memutar operasi gambar mengitari titik pivot. Misalnya, kode
berikut memutar persegi panjang 45 derajat:
Canvas(modifier = Modifier.fillMaxSize()) { rotate(degrees = 45F) { drawRect( color = Color.Gray, topLeft = Offset(x = size.width / 3F, y = size.height / 3F), size = size / 3F ) } }
![Ponsel dengan persegi panjang yang diputar 45 derajat di tengah layar](https://developer.android.com/static/develop/ui/compose/images/graphics/introduction/compose_graphics_canvas_rotate.png?authuser=19&hl=id)
rotate()
untuk menerapkan rotasi ke cakupan gambar saat ini, yang memutar persegi panjang sebesar 45 derajat.
Inset
Gunakan DrawScope.inset()
untuk menyesuaikan parameter default DrawScope
saat ini, yang mengubah batas gambar dan menerjemahkan gambar sesuai parameter tersebut:
Canvas(modifier = Modifier.fillMaxSize()) { val canvasQuadrantSize = size / 2F inset(horizontal = 50f, vertical = 30f) { drawRect(color = Color.Green, size = canvasQuadrantSize) } }
Kode ini menambahkan padding secara efektif ke perintah gambar:
![Persegi panjang yang telah diberi padding](https://developer.android.com/static/develop/ui/compose/images/graphics/introduction/compose_graphics_canvas_inset.png?authuser=19&hl=id)
Beberapa transformasi
Untuk menerapkan beberapa transformasi ke gambar, gunakan
fungsi DrawScope.withTransform()
, yang membuat dan
menerapkan satu transformasi yang menggabungkan semua perubahan yang diinginkan. Menggunakan
withTransform()
lebih efisien daripada membuat panggilan bertingkat ke setiap transformasi,
karena semua transformasi dijalankan bersamaan
dalam satu operasi, bukan Compose yang perlu menghitung dan menyimpan setiap
transformasi bertingkat.
Misalnya, kode berikut menerapkan terjemahan dan rotasi ke persegi panjang:
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 ) } }
![Ponsel dengan kotak yang diputar bergeser ke sisi layar](https://developer.android.com/static/develop/ui/compose/images/graphics/introduction/compose_graphics_multiple_transforms.png?authuser=19&hl=id)
withTransform
untuk menerapkan rotasi dan terjemahan, memutar persegi panjang, dan menggesernya ke kiri.Operasi gambar umum
Menggambar teks
Untuk menggambar teks di Compose, Anda biasanya dapat menggunakan composable Text
. Namun,
jika Anda berada di DrawScope
atau ingin menggambar teks secara manual dengan
penyesuaian, Anda dapat menggunakan
metode
DrawScope.drawText()
.
Untuk menggambar teks, buat TextMeasurer
menggunakan rememberTextMeasurer
dan panggil drawText
dengan pengukur:
val textMeasurer = rememberTextMeasurer() Canvas(modifier = Modifier.fillMaxSize()) { drawText(textMeasurer, "Hello") }
![Menampilkan Halo yang digambar di Canvas](https://developer.android.com/static/develop/ui/compose/images/graphics/introduction/compose_graphics_draw_text.png?authuser=19&hl=id)
Mengukur teks
Cara kerja teks gambar sedikit berbeda dengan perintah gambar lainnya. Biasanya, Anda memberikan perintah gambar ukuran (lebar dan tinggi) untuk menggambar bentuk/gambar. Dengan teks, ada beberapa parameter yang mengontrol ukuran teks yang dirender, seperti ukuran font, font, ligatur, dan spasi huruf.
Dengan Compose, Anda dapat menggunakan TextMeasurer
untuk mendapatkan akses ke ukuran teks
yang diukur, bergantung pada faktor di atas. Jika ingin menggambar latar belakang
di belakang teks, Anda dapat menggunakan informasi terukur untuk mendapatkan ukuran area
yang digunakan teks:
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() )
Cuplikan kode ini menghasilkan latar belakang merah muda pada teks:
![Teks multibaris yang menempati ⅔ dari seluruh area, dengan latar belakang persegi panjang](https://developer.android.com/static/develop/ui/compose/images/graphics/introduction/compose_graphics_canvas_draw_text_measured.png?authuser=19&hl=id)
Menyesuaikan batasan, ukuran font, atau properti apa pun yang memengaruhi ukuran
terukur akan menghasilkan ukuran baru yang dilaporkan. Anda dapat menyetel ukuran tetap untuk width
dan height
, lalu teks akan mengikuti kumpulan TextOverflow
. Misalnya,
kode berikut merender teks dalam ⅓ tinggi dan ⅓ dari lebar
area composable, dan menyetel TextOverflow
ke TextOverflow.Ellipsis
:
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() )
Teks sekarang digambar dalam batasan dengan elipsis di bagian akhir:
![Teks yang digambar dengan latar belakang merah muda, dengan elipsis yang memotong teks.](https://developer.android.com/static/develop/ui/compose/images/graphics/introduction/compose_graphics_canvas_draw_text_ellipsis.png?authuser=19&hl=id)
TextOverflow.Ellipsis
dengan batasan tetap untuk mengukur teks.Membuat gambar
Untuk menggambar ImageBitmap
dengan DrawScope
, muat gambar menggunakan ImageBitmap.imageResource()
, lalu panggil drawImage
:
val dogImage = ImageBitmap.imageResource(id = R.drawable.dog) Canvas(modifier = Modifier.fillMaxSize(), onDraw = { drawImage(dogImage) })
![Gambar seekor anjing yang digambar di Canvas](https://developer.android.com/static/develop/ui/compose/images/graphics/introduction/compose_graphics_canvas_image.png?authuser=19&hl=id)
ImageBitmap
di Canvas.Menggambar bentuk dasar
Ada banyak fungsi menggambar bentuk di DrawScope
. Untuk menggambar bentuk, gunakan salah satu dari
fungsi gambar yang telah ditetapkan, seperti drawCircle
:
val purpleColor = Color(0xFFBA68C8) Canvas( modifier = Modifier .fillMaxSize() .padding(16.dp), onDraw = { drawCircle(purpleColor) } )
API |
Output |
![]() |
|
![]() |
|
![]() |
|
![]() |
|
![]() |
|
![]() |
|
![]() |
Menggambar path
Path adalah serangkaian petunjuk matematika yang menghasilkan gambar setelah
dieksekusi. DrawScope
dapat menggambar path menggunakan metode DrawScope.drawPath()
.
Misalnya, Anda ingin menggambar segitiga. Anda dapat membuat path dengan
fungsi seperti lineTo()
dan moveTo()
menggunakan ukuran area gambar.
Kemudian, panggil drawPath()
dengan jalur yang baru dibuat ini untuk membuat bentuk segitiga.
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() )
![Segitiga path ungu terbalik yang digambar di Compose](https://developer.android.com/static/develop/ui/compose/images/graphics/introduction/compose_graphics_canvas_draw_path.png?authuser=19&hl=id)
Path
di Compose.Mengakses objek Canvas
Dengan DrawScope
, Anda tidak memiliki akses langsung ke objek Canvas
. Anda dapat menggunakan DrawScope.drawIntoCanvas()
untuk mendapatkan akses ke objek Canvas
yang dapat Anda gunakan untuk memanggil fungsi.
Misalnya, jika Anda memiliki Drawable
kustom yang ingin digambar ke kanvas, Anda dapat mengakses kanvas dan memanggil Drawable#draw()
, dengan meneruskan
objek Canvas
:
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() )
![ShapeDrawable hitam oval dengan ukuran penuh](https://developer.android.com/static/develop/ui/compose/images/graphics/introduction/compose_graphics_canvas_draw_into_canvas.png?authuser=19&hl=id)
Drawable
.Mempelajari lebih lanjut
Untuk informasi selengkapnya tentang Menggambar di Compose, lihat referensi berikut:
- Pengubah Grafik - Pelajari berbagai jenis pengubah gambar.
- Kuas - Pelajari cara menyesuaikan proses menggambar konten Anda.
- Tata Letak dan Grafik Kustom di Compose - Android Dev Summit 2022 - Pelajari cara mem-build UI kustom di Compose dengan Tata Letak dan Grafik.
- Contoh JetLagged - Contoh Compose yang menunjukkan cara menggambar grafik kustom.
Direkomendasikan untuk Anda
- Catatan: teks link ditampilkan saat JavaScript nonaktif
- Pengubah Grafis
- Grafis di Compose
- Garis perataan di Jetpack Compose