Anda dapat menentukan konfigurasi penampung Petak untuk membuat tata letak fleksibel yang merespons berbagai ukuran layar dan jenis konten. Halaman ini menjelaskan cara melakukan hal berikut:
- Tentukan petak: Siapkan struktur dasar baris dan kolom.
- Menempatkan item dalam petak: Pahami cara menempatkan item ke dalam sel petak dan cara mengubah arah alur.
- Mengelola ukuran trek: Gunakan ukuran tetap, persentase, fleksibel, dan intrinsik untuk menetapkan ukuran trek.
- Mengatur jarak: Mengelola "ruang" di antara baris dan kolom.
Menentukan petak
Petak terdiri dari kolom dan baris.
Composable Grid memiliki parameter config
yang menerima lambda untuk menentukan kolom dan baris
dalam GridConfigurationScope.
Contoh berikut menentukan petak yang memiliki tiga baris dan dua kolom,
masing-masing dengan ukuran tetap yang ditentukan dalam Dp:
Grid( config = { repeat(2) { column(160.dp) } repeat(3) { row(90.dp) } } ) { }
Menempatkan item dalam petak
Grid mengambil elemen UI
dalam lambda content dan menempatkannya ke dalam sel petak.
Petak mengatur item terlepas dari
apakah Anda telah menentukan baris dan kolom secara eksplisit.
Secara default,
Grid mencoba menempatkan elemen UI di sel petak yang tersedia di baris;
jika tidak dapat, elemen tersebut akan ditempatkan di sel petak yang tersedia di baris berikutnya.
Jika tidak ada sel kosong, Grid akan membuat baris baru.
Dalam contoh berikut, petak memiliki enam sel petak
dan menempatkan kartu ke setiap sel (Gambar 1).
Setiap sel petak berukuran 160dp x 90dp,
sehingga ukuran total petak adalah 320dp x 270dp.
Grid( config = { repeat(2) { column(160.dp) } repeat(3) { row(90.dp) } } ) { Card1() Card2() Card3() Card4() Card5() Card6() }
Untuk mengubah perilaku default ini menjadi pengisian menurut kolom,
tetapkan properti flow ke GridFlow.Column.
Grid( config = { repeat(2) { column(160.dp) } repeat(3) { row(90.dp) } gap(8.dp) flow = GridFlow.Column // Grid tries to place items to fill the column }, ) { Card1() Card2() Card3() Card4() Card5() Card6() }
GridFlow.Row (kiri) dan GridFlow.Column (kanan).
Mengelola ukuran trek
Baris dan kolom secara kolektif disebut sebagai jalur petak. Anda dapat menentukan ukuran jalur petak menggunakan salah satu metode berikut:
- Tetap (
Dp): Mengalokasikan ukuran tertentu (misalnya,column(180.dp)). - Persentase (
Float): Mengalokasikan persentase total ruang yang tersedia dari0.0fhingga1.0f(misalnya,row(0.5f)untuk 50%). - Fleksibel (
Fr): Mendistribusikan ruang yang tersisa secara proporsional setelah jalur tetap dan persentase dihitung. Misalnya, jika dua baris ditetapkan ke1.frdan3.fr, baris terakhir akan menerima 75% dari tinggi yang tersisa. - Intrinsik: Mengatur ukuran jalur berdasarkan konten di dalamnya. Untuk mengetahui informasi selengkapnya, lihat Menentukan ukuran jalur petak secara intrinsik.
Contoh berikut menggunakan berbagai opsi ukuran trek untuk menentukan tinggi baris:
Grid( config = { column(1f) row(100.dp) row(0.2f) row(1.fr) row(GridTrackSize.Auto) }, modifier = Modifier.height(480.dp) ) { PastelRedCard("Fixed(100.dp)") PastelGreenCard("Percentage(0.2f)") PastelBlueCard("Flex(1.fr)") PastelYellowCard("Auto") }
Grid.
Menetapkan ukuran minimum untuk jalur petak fleksibel
Jika tidak ada ruang tersisa di penampung petak,
jalur fleksibel standar dapat menyusut menjadi 0.dp.
Untuk mencegah hal ini dan memastikan konten tidak terkompresi,
gunakan GridTrackSize.MinMax
untuk menerapkan ukuran minimum eksplisit sambil menjaga agar jalur tetap fleksibel.
Contoh berikut mengalokasikan setidaknya 100.dp ke baris pertama:
Grid( config = { column(1f) // The first row has a minimum height of 100.dp and can expand to // the half of the remaining space. row(GridTrackSize.MinMax(100.dp, 1.fr)) // The second row takes the half of the remaining space. row(1.fr) // The third row has a fixed height of 200.dp. row(200.dp) }, modifier = Modifier.size(360.dp) // Total grid height is 360.dp ) { PastelRedCard("MinMax(100.dp, 1.fr)") PastelGreenCard("Flex(1.fr)") PastelBlueCard("Fixed(200.dp)") }
100.dp.
Menetapkan ukuran trek petak minimum untuk menempatkan daftar lambat
Jalur fleksibel standar secara otomatis mengkueri ukuran intrinsik
turunannya untuk menentukan ukuran dasar.
Namun, Jetpack Compose melarang kueri ukuran intrinsik
SubcomposeLayout, yang mendukung komponen,
seperti LazyColumn dan LazyRow.
Menempatkan daftar lambat di dalam jalur fleksibel standar menyebabkan error IllegalStateException.
Untuk menempatkan daftar lambat dengan aman di dalam jalur petak yang fleksibel,
gunakan MinMax dengan ukuran minimum eksplisit (seperti 0.dp)
untuk melewati proses pengukuran intrinsik.
Grid( config = { column(1f) // The first row's height is determined by the height of the Text composable. row(GridTrackSize.Auto) // The second row occupies the remaining space, allowing the LazyColumn to scroll. row(GridTrackSize.MinMax(0.dp, 1.fr)) gap(8.dp) }, modifier = Modifier.size(width = 170.dp, height = 240.dp) ) { Text("LazyColumn in a Grid") // The LazyColumn is placed in the second row, filling the remaining space. LazyColumn(verticalArrangement = Arrangement.spacedBy(4.dp)) { items(100) { number -> PastelGreenCard("Card $number") } } }
LazyColumn dalam sel petak.
Menentukan ukuran jalur petak secara intrinsik
Anda dapat menggunakan pengukuran intrinsik untuk Grid
jika Anda ingin tata letak beradaptasi dengan konten,
daripada memaksanya masuk ke dalam penampung tetap.
Ukuran jalur petak ditentukan dengan nilai berikut:
GridTrackSize.MaxContent: Gunakan ukuran intrinsik maksimum konten (misalnya, lebar ditentukan oleh panjang penuh teks dalam blok teks tanpa pengemasan).GridTrackSize.MinContent: Menggunakan ukuran intrinsik minimum konten (misalnya, lebar ditentukan oleh satu kata terpanjang dalam blok teks).GridTrackSize.Auto: Gunakan ukuran fleksibel untuk jalur yang beradaptasi berdasarkan ruang yang tersedia. Secara default, berperilaku sepertiMaxContent, tetapi mengecilkan dan membungkus kontennya agar sesuai dengan penampung induk.
Contoh berikut menempatkan dua teks berdampingan. Ukuran kolom untuk teks pertama ditentukan oleh lebar minimum yang diperlukan untuk menampilkan teks, dan lebar kolom kedua bergantung pada lebar maksimum yang diperlukan untuk teks.
Grid( config = { column(GridTrackSize.MinContent) column(GridTrackSize.MaxContent) row(1.0f) }, modifier = Modifier.width(480.dp) ) { Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras imperdiet.") Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras imperdiet.") }
Menetapkan jarak antar-baris dan kolom
Setelah ukuran trek petak ditentukan,
Anda dapat mengubah jarak petak untuk menyempurnakan jarak antar-trek.
Anda dapat menentukan jarak kolom dengan fungsi columnGap,
dan jarak baris dengan rowGap. Dalam contoh berikut,
ada jarak 16dp di antara setiap baris,
dan jarak 8dp di antara setiap kolom (Gambar 5).
Grid( config = { repeat(2) { column(160.dp) } repeat(3) { row(90.dp) } rowGap(16.dp) columnGap(8.dp) } ) { Card1() Card2() Card3() Card4() Card5() Card6() }
Anda juga dapat menggunakan fungsi praktis gap
untuk menentukan celah dengan ukuran kolom dan baris yang sama,
serta untuk menentukan ukuran kolom dan celah secara terpisah menggunakan satu fungsi.
Kode berikut menambahkan jarak 8dp ke petak:
Grid( config = { repeat(2) { column(160.dp) } repeat(3) { row(90.dp) } gap(8.dp) // Equivalent to columnGap(8.dp) and rowGap(8.dp) } ) { Card1() Card2() Card3() Card4() Card5() Card6() }
Menentukan area petak dengan area bernama
Area bernama memungkinkan Anda melampirkan nama ke grup sel petak, yang disebut area petak. Anda dapat menggunakan nama ini, bukan indeks koordinat saat menempatkan elemen UI dalam petak.
Penggunaan area bernama memiliki dua manfaat utama untuk keterbacaan kode:
- Saat menentukan tata letak petak, tujuan dan penempatan konten yang diharapkan sudah jelas.
- Saat menambahkan konten, tujuan konten tersebut jelas.
Untuk mengatur tata letak yang kompleks dengan jelas, Anda dapat memisahkan struktur petak fisik dari penempatan turunan dengan menentukan area petak semantik.
Di dalam lambda config, gunakan fungsi area di
GridConfigurationScope untuk mendaftarkan area bernama dalam petak.
Kemudian, Anda dapat menetapkan composable turunan ke area ini
menggunakan pengubah gridItem
dengan ID area yang sesuai. Fungsi area memetakan
ID semantik (seperti nilai class enum atau kunci string) ke
sekumpulan koordinat petak fisik. Garis petak dan indeks berbasis 1
(yaitu, baris pertama adalah 1, dan kolom pertama adalah 1).
Misalnya, Anda menentukan petak yang memiliki empat ID area:
/** * An enum representing the IDs for named areas within the grid. */ enum class GridAreaNames { Area1, Area2, Area3, Area4 }
Berikan nama untuk area menggunakan parameter areaId bersama dengan rentang dan koordinat sel area.
Pengubah gridItem menggunakan areaId sebagai kunci
untuk menetapkan setiap item turunan ke area petak yang ditentukan,
seperti yang ditunjukkan dalam contoh berikut:
Grid( config = { // Define a single column that takes all available width. repeat(2) { column(0.5f) } // Define four rows, each taking 25% of the total height. repeat(4) { row(0.25f) } // Define named grid areas by associating an areaId with specific row and column indices. // Row and column indices are 1-based. area(areaId = GridAreaNames.Area1, row = 1, column = 1, columnSpan = 2) area(areaId = GridAreaNames.Area2, row = 2, column = 1, rowSpan = 3) area(areaId = GridAreaNames.Area3, rows = 2..3, columns = 2..2) area(areaId = GridAreaNames.Area4, row = 4, column = 2) gap(4.dp) }, modifier = Modifier.size(360.dp) ) { PastelRedCard( "Area 1", // Use Modifier.gridItem(areaId) to place this composable into the // grid area defined with the matching ID in the config block. modifier = Modifier.gridItem(areaId = GridAreaNames.Area1) ) PastelGreenCard( "Area 2", modifier = Modifier.gridItem(areaId = GridAreaNames.Area2) ) PastelBlueCard( "Area 3", modifier = Modifier.gridItem(areaId = GridAreaNames.Area3) ) PastelYellowCard( "Area 4", modifier = Modifier.gridItem(areaId = GridAreaNames.Area4) ) }
Dengan menggunakan area bernama, Anda dapat mengatur ulang atau menyesuaikan petak tata letak fisik (misalnya, mengubah baris, kolom, atau ukuran jalur) di lambda config tanpa perlu mengubah urutan atau parameter composable turunan.