Salah satu aturan Compose adalah Anda seharusnya hanya mengukur turunan satu kali; mengukur turunan dua kali akan memunculkan pengecualian runtime. Namun, ada kalanya Anda memerlukan beberapa informasi tentang turunan Anda sebelum mengukurnya.
Intrinsik memungkinkan Anda membuat kueri turunan sebelum benar-benar diukur.
Ke composable, Anda dapat meminta IntrinsicSize.Min atau IntrinsicSize.Max:
Modifier.width(IntrinsicSize.Min)- Berapa lebar minimum yang Anda perlukan untuk menampilkan konten dengan benar?Modifier.width(IntrinsicSize.Max)- Berapa lebar maksimum yang Anda butuhkan untuk menampilkan konten dengan benar?Modifier.height(IntrinsicSize.Min)- Berapa tinggi minimum yang Anda butuhkan untuk menampilkan konten dengan benar?Modifier.height(IntrinsicSize.Max)- Berapa tinggi maksimum yang Anda perlukan untuk menampilkan konten dengan benar?
Misalnya, jika Anda meminta minIntrinsicHeight dari Text dengan batasan width
yang tidak terbatas dalam tata letak kustom, variabel ini akan menampilkan height dari Text
dengan teks yang digambar dalam satu baris.
Cara kerja intrinsik
Anda dapat membuat composable yang menampilkan dua teks di layar yang dipisahkan oleh pemisah:
Untuk melakukannya, gunakan Row dengan dua composable Text yang mengisi ruang yang tersedia, dan Divider di tengah. Divider harus setinggi
Text tertinggi, dan harus tipis (width = 1.dp).
@Composable fun TwoTexts(modifier: Modifier = Modifier, text1: String, text2: String) { Row(modifier = modifier) { Text( modifier = Modifier .weight(1f) .padding(start = 4.dp) .wrapContentWidth(Alignment.Start), text = text1 ) VerticalDivider( color = Color.Black, modifier = Modifier.fillMaxHeight().width(1.dp) ) Text( modifier = Modifier .weight(1f) .padding(end = 4.dp) .wrapContentWidth(Alignment.End), text = text2 ) } }
Divider meluas ke seluruh layar, yang bukan merupakan perilaku yang diinginkan:
Hal ini terjadi karena Row mengukur setiap turunan secara individual, dan tinggi
Text tidak dapat digunakan untuk membatasi Divider.
Agar Divider mengisi ruang yang tersedia dengan ketinggian tertentu,
gunakan pengubah height(IntrinsicSize.Min).
height(IntrinsicSize.Min) mengukur ukuran turunannya agar setinggi tinggi intrinsik minimumnya. Karena pengubah ini bersifat rekursif, pengubah ini membuat kueri
minIntrinsicHeight dari Row dan turunannya.
Menerapkan pengubah ini ke kode Anda akan membuatnya berfungsi seperti yang diharapkan:
@Composable fun TwoTexts(modifier: Modifier = Modifier, text1: String, text2: String) { Row(modifier = modifier.height(IntrinsicSize.Min)) { Text( modifier = Modifier .weight(1f) .padding(start = 4.dp) .wrapContentWidth(Alignment.Start), text = text1 ) VerticalDivider( color = Color.Black, modifier = Modifier.fillMaxHeight().width(1.dp) ) Text( modifier = Modifier .weight(1f) .padding(end = 4.dp) .wrapContentWidth(Alignment.End), text = text2 ) } } // @Preview @Composable fun TwoTextsPreview() { MaterialTheme { Surface { TwoTexts(text1 = "Hi", text2 = "there") } } }
Dengan pratinjau:
Tinggi Row ditentukan sebagai berikut:
minIntrinsicHeightcomposableRowadalahminIntrinsicHeightmaksimum dari turunannya.minIntrinsicHeightelemenDivideradalah 0, karena tidak menempati ruang jika tidak ada batasan yang diberikan.TextminIntrinsicHeightadalah teks untukwidthtertentu.- Oleh karena itu, batasan
heightRowelemen akan menjadiminIntrinsicHeightmaksimum dariText. Dividerkemudian memperluasheight-nya ke batasanheightyang diberikan olehRow.
Intrinsik di tata letak kustom
Saat membuat pengubah Layout atau layout kustom, pengukuran intrinsik
dihitung secara otomatis berdasarkan perkiraan. Oleh karena itu,
penghitungan mungkin tidak tepat untuk semua tata letak. API ini menawarkan opsi
untuk mengganti perilaku default tersebut.
Untuk menentukan pengukuran intrinsik Layout kustom Anda, ganti
minIntrinsicWidth, minIntrinsicHeight, maxIntrinsicWidth, dan
maxIntrinsicHeight dari antarmuka MeasurePolicy saat membuatnya.
@Composable fun MyCustomComposable( modifier: Modifier = Modifier, content: @Composable () -> Unit ) { Layout( content = content, modifier = modifier, measurePolicy = object : MeasurePolicy { override fun MeasureScope.measure( measurables: List<Measurable>, constraints: Constraints ): MeasureResult { // Measure and layout here // ... } override fun IntrinsicMeasureScope.minIntrinsicWidth( measurables: List<IntrinsicMeasurable>, height: Int ): Int { // Logic here // ... } // Other intrinsics related methods have a default value, // you can override only the methods that you need. } ) }
Saat membuat pengubah layout kustom, ganti metode terkait
di antarmuka LayoutModifier.
fun Modifier.myCustomModifier(/* ... */) = this then object : LayoutModifier { override fun MeasureScope.measure( measurable: Measurable, constraints: Constraints ): MeasureResult { // Measure and layout here // ... } override fun IntrinsicMeasureScope.minIntrinsicWidth( measurable: IntrinsicMeasurable, height: Int ): Int { // Logic here // ... } // Other intrinsics related methods have a default value, // you can override only the methods that you need. }
Direkomendasikan untuk Anda
- Catatan: teks link ditampilkan saat JavaScript nonaktif
- Tata letak kustom {:#custom-layouts}
- Garis perataan di Jetpack Compose
- Fase Jetpack Compose