Di Compose, Anda dapat merangkai beberapa pengubah untuk mengubah tampilan dan nuansa composable. Rantai pengubah ini dapat memengaruhi batasan yang diteruskan ke composable, yang menentukan batas lebar dan tinggi.
Halaman ini menjelaskan pengaruh pengubah berantai terhadap batasan dan, pada gilirannya, pengukuran dan penempatan composable.
Pengubah dalam hierarki UI
Untuk memahami pengaruh pengubah satu sama lain, sebaiknya visualisasikan tampilannya di hierarki UI, yang dihasilkan selama fase komposisi. Untuk mengetahui informasi selengkapnya, lihat bagian Komposisi.
Di hierarki UI, Anda dapat memvisualisasikan pengubah sebagai node wrapper untuk node tata letak:
Menambahkan lebih dari satu pengubah ke composable akan membuat rantai pengubah. Saat
Anda merangkai beberapa pengubah, setiap node pengubah menggabungkan sisa rantai
dan node tata letak di dalamnya. Misalnya, saat Anda merangkai pengubah clip dan
size, node pengubah clip akan menggabungkan node pengubah size,
yang kemudian menggabungkan node tata letak Image.
Pada fase tata letak, algoritma yang menelusuri hierarki tetap sama, tetapi setiap node pengubah juga dikunjungi. Dengan cara ini, pengubah dapat mengubah persyaratan ukuran dan penempatan pengubah atau node tata letak yang digabungkannya.
Seperti yang ditunjukkan pada Gambar 2, implementasi composable Image dan Text
itu sendiri terdiri dari rantai pengubah yang menggabungkan satu node tata letak.
Implementasi Row dan Column adalah node tata letak yang menjelaskan cara
menata letak turunannya.
Ringkasnya:
- Pengubah menggabungkan satu pengubah atau node tata letak.
- Node tata letak dapat menata letak beberapa node turunan.
Bagian berikut menjelaskan cara menggunakan model mental ini untuk memahami pembuatan rantai pengubah dan pengaruhnya terhadap ukuran composable.
Batasan dalam fase tata letak
Fase tata letak mengikuti algoritma tiga langkah untuk menemukan lebar, tinggi, dan koordinat x, y setiap node tata letak:
- Mengukur turunan: Node mengukur turunannya, jika ada.
- Menentukan ukuran sendiri: Berdasarkan pengukuran tersebut, node menentukan ukurannya sendiri.
- Menempatkan turunan: Setiap node turunan ditempatkan relatif terhadap posisi node itu sendiri.
Constraints membantu menemukan ukuran yang tepat untuk node selama dua langkah pertama algoritma. Batasan menentukan batas minimum dan maksimum untuk
lebar dan tinggi node. Saat node menentukan ukurannya, ukuran terukurnya
harus berada dalam rentang ukuran ini.
Jenis batasan
Batasan dapat berupa salah satu dari berikut:
- Terikat: Node memiliki lebar dan tinggi maksimum dan minimum.
- Tidak terbatas: Node tidak dibatasi untuk ukuran apa pun. Batas lebar dan tinggi maksimum ditetapkan ke tak terbatas.
- Exact: Node diminta untuk mengikuti persyaratan ukuran yang tepat. Batas minimum dan maksimum ditetapkan ke nilai yang sama.
- Combination: Node mengikuti kombinasi jenis batasan sebelumnya. Misalnya, batasan dapat membatasi lebar sekaligus memungkinkan tinggi maksimum yang tidak terbatas, atau menetapkan lebar yang tepat, tetapi memberikan tinggi yang terbatas.
Bagian berikutnya menjelaskan cara batasan ini diteruskan dari induk ke turunan.
Cara batasan diteruskan dari induk ke turunan
Selama langkah pertama algoritma yang dijelaskan dalam Batasan dalam fase tata letak, batasan diteruskan dari induk ke turunan dalam hierarki UI.
Saat mengukur turunannya, node induk memberikan batasan ini kepada setiap turunan untuk memberi tahu seberapa besar atau kecil ukuran yang diizinkan. Kemudian, saat menentukan ukurannya sendiri, elemen tersebut juga mematuhi batasan yang diteruskan oleh induknya sendiri.
Secara garis besar, algoritma ini bekerja dengan cara berikut:
- Untuk menentukan ukuran yang sebenarnya ingin ditempati, node root di hierarki UI mengukur turunannya dan meneruskan batasan yang sama ke turunan pertamanya.
- Jika turunan adalah pengubah yang tidak memengaruhi pengukuran, turunan akan meneruskan batasan ke pengubah berikutnya. Batasan diteruskan ke rantai pengubah apa adanya, kecuali jika pengubah yang memengaruhi pengukuran tercapai. Batasan kemudian diubah ukurannya.
- Setelah mencapai node yang tidak memiliki turunan (disebut sebagai "node daun"), node tersebut akan menentukan ukurannya berdasarkan batasan yang diteruskan, dan menampilkan ukuran yang telah ditentukan ini ke induknya.
- Induk menyesuaikan batasannya berdasarkan pengukuran turunan ini, dan memanggil turunan berikutnya dengan batasan yang disesuaikan ini.
- Setelah semua turunan dari induk diukur, node induk akan menentukan ukurannya sendiri dan mengomunikasikannya ke induknya sendiri.
- Dengan cara ini, seluruh hierarki dilalui secara depth-first. Pada akhirnya, semua node telah menentukan ukurannya, dan langkah pengukuran selesai.
Untuk contoh mendalam, lihat video Batasan dan urutan pengubah.
Pengubah yang memengaruhi batasan
Di bagian sebelumnya, Anda telah mempelajari bahwa beberapa pengubah dapat memengaruhi ukuran batasan. Bagian berikut menjelaskan pengubah tertentu yang memengaruhi batasan.
Pengubah size
Pengubah size mendeklarasikan ukuran konten yang diinginkan.
Misalnya, hierarki UI berikut harus dirender dalam penampung 300dp
oleh 200dp. Batasan dibatasi, sehingga memungkinkan lebar antara 100dp dan
300dp, serta tinggi antara 100dp dan 200dp:
Pengubah size menyesuaikan batasan yang masuk agar sesuai dengan nilai yang diteruskan ke pengubah tersebut.
Dalam contoh ini, nilainya adalah 150dp:
size menyesuaikan batasan menjadi 150dp.Jika lebar dan tinggi lebih kecil dari batas batasan terkecil, atau lebih besar dari batas batasan terbesar, pengubah akan mencocokkan batasan yang diteruskan sedekat mungkin sambil tetap mematuhi batasan yang diteruskan:
size mematuhi batasan yang diteruskan sedekat
mungkin.Perhatikan bahwa merangkai beberapa pengubah size tidak akan berfungsi. Pengubah size
pertama menetapkan batasan minimum dan maksimum ke nilai tetap. Meskipun
pengubah ukuran kedua meminta ukuran yang lebih kecil atau lebih besar, pengubah ukuran tersebut masih harus
mematuhi batas persis yang diteruskan, sehingga tidak akan mengganti nilai tersebut:
size, dengan nilai kedua yang diteruskan (50dp) tidak menggantikan nilai pertama (100dp).Pengubah requiredSize
Gunakan pengubah requiredSize, bukan size, jika Anda memerlukan
node untuk mengganti batasan yang masuk. Pengubah requiredSize menggantikan batasan yang masuk dan meneruskan ukuran yang Anda tentukan sebagai batas yang tepat.
Saat ukuran diteruskan kembali ke hierarki, node turunan akan dipusatkan di ruang yang tersedia:
requiredSize mengganti batasan yang masuk dari
pengubah size.Pengubah width dan height
Pengubah size menyesuaikan lebar dan tinggi batasan. Dengan
pengubah width, Anda dapat menetapkan lebar tetap, tetapi membiarkan tingginya tidak ditentukan.
Demikian pula, dengan pengubah height, Anda dapat menetapkan tinggi tetap, tetapi membiarkan
lebar tidak ditentukan:
width dan pengubah height masing-masing menetapkan lebar dan tinggi tetap.Pengubah sizeIn
Pengubah sizeIn memungkinkan Anda menetapkan batasan minimum dan maksimum yang tepat
untuk lebar dan tinggi. Gunakan pengubah sizeIn jika Anda memerlukan kontrol terperinci
atas batasan.
sizeIn dengan minWidth, maxWidth, minHeight, dan
maxHeight ditetapkan.Contoh
Bagian ini menampilkan dan menjelaskan output dari beberapa cuplikan kode dengan pengubah berantai.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .size(50.dp) )
Cuplikan ini menghasilkan output berikut:
Image mengisi ukuran maksimum sebagai
hasil dari rantai pengubah.- Pengubah
fillMaxSizemengubah batasan untuk menetapkan lebar dan tinggi minimum ke nilai maksimum — lebar300dpdan tinggi200dp. - Meskipun pengubah
sizeingin menggunakan ukuran50dp, pengubah tersebut masih harus mematuhi batasan minimum yang masuk. Jadi, pengubahsizejuga akan menghasilkan batas batasan yang tepat dari300sebesar200, yang secara efektif mengabaikan nilai yang diberikan dalam pengubahsize. Imagemengikuti batas ini dan melaporkan ukuran300x200, yang diteruskan ke seluruh hierarki.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .wrapContentSize() .size(50.dp) )
Cuplikan ini menghasilkan output berikut:
Image dipusatkan dan diubah ukurannya menjadi
50dp.- Pengubah
fillMaxSizemenyesuaikan batasan untuk menetapkan lebar dan tinggi minimum ke nilai maksimum — lebar300dp, dan tinggi200dp. - Pengubah
wrapContentSizemereset batasan minimum. Jadi, meskipunfillMaxSizemenghasilkan batasan tetap,wrapContentSizemeresetnya kembali ke batasan terbatas. Node berikut kini dapat menggunakan seluruh ruang lagi, atau lebih kecil dari seluruh ruang. - Pengubah
sizemenetapkan batasan ke batas minimum dan maksimum50. Imagedi-resolve ke ukuran50kali50, dan pengubahsizemeneruskannya.- Pengubah
wrapContentSizememiliki properti khusus. Class ini mengambil elemen turunannya dan menempatkannya di tengah batas minimum yang tersedia yang diteruskan ke class tersebut. Oleh karena itu, ukuran yang dikomunikasikan ke induknya sama dengan batas minimum yang diteruskan ke dalamnya.
Dengan menggabungkan tiga pengubah saja, Anda dapat menentukan ukuran composable dan memusatkannya di induknya.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .clip(CircleShape) .padding(10.dp) .size(100.dp) )
Cuplikan ini menghasilkan output berikut:
- Pengubah
cliptidak mengubah batasan. - Pengubah
paddingmenurunkan batasan maksimum. - Pengubah
sizemenetapkan semua batasan ke100dp. Imagemematuhi batasan tersebut dan melaporkan ukuran100dpkali100dp.- Pengubah
paddingmenambahkan10dpdi semua sisi ke ukuran yang dilaporkan olehImage, sehingga tata letak dengan padding melaporkan lebar dan tinggi120dp. - Sekarang, dalam fase gambar, pengubah
clipbertindak pada kanvas120dpkali120dp. Tindakan ini akan membuat mask lingkaran dengan ukuran tersebut. - Pengubah
paddingkemudian menyisipkan kontennya sebesar10dpdi semua sisi, yang menurunkan ukuran kanvas untukImagemenjadi100dpkali100dp. Imagedigambar di kanvas yang lebih kecil tersebut. Gambar dipotong berdasarkan lingkaran asli120dp, sehingga outputnya adalah hasil yang tidak bulat.