Batasan dan urutan pengubah

Di Compose, Anda dapat menggabungkan beberapa pengubah untuk mengubah tampilan dan dari composable. Rantai pengubah ini dapat memengaruhi batasan yang diteruskan ke composable, yang menentukan batas lebar dan tinggi.

Halaman ini menjelaskan bagaimana pengubah berantai memengaruhi batasan dan, pada gilirannya, pengukuran dan penempatan composable.

Pengubah dalam hierarki UI

Untuk memahami pengaruh pengubah satu sama lain, sebaiknya visualisasikan cara pengubah muncul di hierarki UI, yang dihasilkan selama fase komposisi. Sebagai mengetahui informasi selengkapnya, lihat bagian Komposisi.

Dalam hierarki UI, Anda dapat memvisualisasikan pengubah sebagai node wrapper untuk node tata letak:

Kode untuk composable dan pengubah, serta representasi visualnya sebagai hierarki UI.
Gambar 1. Pengubah yang menggabungkan node tata letak dalam hierarki UI.

Menambahkan lebih dari satu pengubah ke composable akan membuat rantai pengubah. Kapan Anda merangkai beberapa pengubah, setiap node pengubah menggabungkan sisa rantai dan node tata letak di dalamnya. Misalnya, saat Anda membuat rantai 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 ukuran persyaratan dan penempatan node pengubah atau tata letak yang digabungkannya.

Seperti yang ditunjukkan dalam Gambar 2, implementasi composable Image dan Text sendiri terdiri dari rantai pengubah yang menggabungkan satu node tata letak. Implementasi Row dan Column hanyalah node tata letak yang menjelaskan cara menyusun turunannya.

Struktur hierarki dari sebelumnya, tetapi sekarang setiap node hanyalah tata letak sederhana, dengan banyak node pengubah yang menggabungkannya.
Gambar 2. Struktur hierarki yang sama seperti pada Gambar 1, tetapi dengan composable dalam hierarki UI yang divisualisasi sebagai rantai pengubah.

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 rantai pengubah dan pengaruhnya terhadap ukuran composable.

Batasan dalam fase tata letak

Fase tata letak mengikuti algoritma tiga langkah untuk menemukan setiap tata letak lebar, tinggi, serta koordinat x, y dari node:

  1. Mengukur turunan: Node mengukur turunannya, jika ada.
  2. Menentukan ukuran sendiri: Berdasarkan pengukuran tersebut, node memutuskan sendiri ukuran.
  3. Turunan tempat: Setiap node turunan ditempatkan relatif terhadap node sendiri posisi Anda.

Constraints membantu menemukan ukuran yang tepat untuk node selama dua node pertama langkah-langkah algoritma. {i>Contraints<i} menentukan batas minimum dan maksimum untuk untuk lebar dan tinggi node. Saat node memutuskan ukurannya, ukuran yang diukurnya harus berada dalam rentang ukuran ini.

Jenis batasan

Batasan dapat berupa salah satu dari hal berikut:

  • Terbatas: Node memiliki lebar dan tinggi maksimum dan minimum.
Batasan berbatas dari berbagai ukuran dalam satu container.
Gambar 3. Batasan yang dibatasi.
  • Tidak dibatasi: Node tidak dibatasi dalam ukuran apa pun. Batas lebar dan tinggi maksimum ditetapkan ke tak terbatas.
Batasan tak terbatas yang memiliki lebar dan tinggi yang ditetapkan ke tak terhingga. Batasan melampaui container.
Gambar 4. Batasan tidak terbatas.
  • Persis: Node diminta untuk mengikuti persyaratan ukuran yang tepat. Batas minimum dan maksimum ditetapkan ke nilai yang sama.
Batasan persis yang sesuai dengan persyaratan ukuran persis dalam penampung.
Gambar 5. Batasan persis.
  • Kombinasi: Node mengikuti kombinasi jenis batasan di atas. Misalnya, batasan bisa membatasi lebar sekaligus memungkinkan tinggi maksimum tidak terbatas, atau menetapkan lebar yang tepat, tetapi memberikan tinggi terbatas.
Dua penampung yang menampilkan kombinasi batasan terbatas dan tidak terbatas serta lebar dan tinggi yang tepat.
Gambar 6. Kombinasi batasan terbatas dan tidak terbatas serta lebar dan tinggi yang tepat.

Bagian berikutnya akan menjelaskan cara batasan ini diteruskan dari induk ke anak.

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 node induk mengukur turunannya, node induk akan memberikan batasan ini ke setiap turunan untuk memberi tahu mereka seberapa besar atau kecil ukuran yang diizinkan. Kemudian, saat menentukan ukurannya sendiri, elemen ini juga mematuhi batasan yang diteruskan oleh induk elemen tersebut.

Pada tingkat tinggi, algoritma berfungsi dengan cara berikut:

  1. Untuk menentukan ukuran yang sebenarnya ingin diduduki, node root dalam hierarki UI akan mengukur turunannya dan meneruskan batasan yang sama ke turunan pertamanya.
  2. Jika turunan adalah pengubah yang tidak memengaruhi pengukuran, turunan akan meneruskan batasan ke pengubah berikutnya. Batasan diturunkan dari pengubah rantai apa adanya kecuali jika pengubah yang memengaruhi pengukuran tercapai. Batasan kemudian diubah ukurannya.
  3. Setelah node yang tidak memiliki turunan (disebut sebagai "node daun") dicapai, node tersebut akan menentukan ukurannya berdasarkan batasan yang diteruskan, dan menampilkan ukuran yang di-resolve ini ke induknya.
  4. Induk menyesuaikan batasannya berdasarkan pengukuran turunan ini, dan memanggil turunan berikutnya dengan batasan yang disesuaikan ini.
  5. Setelah semua turunan dari induk diukur, node induk akan memutuskan ukurannya sendiri dan mengomunikasikannya kepada induknya.
  6. Dengan cara ini, seluruh pohon akan dilalui kedalaman terlebih dahulu. Akhirnya, semua {i>node<i} telah memutuskan ukurannya, dan langkah pengukuran selesai.

Untuk contoh mendalam, lihat video Urutan batasan dan pengubah.

Pengubah yang memengaruhi batasan

Anda telah mempelajari di bagian sebelumnya 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 lebar antara 100dp dan 300dp, dan tinggi antara 100dp dan 200dp:

Bagian dari hierarki UI dengan pengubah ukuran yang menggabungkan node tata letak, dan
  representasi dari batasan terbatas yang ditetapkan oleh pengubah ukuran dalam penampung.
Gambar 7. Batasan terbatas dalam hierarki UI dan representasinya dalam penampung.

Pengubah size menyesuaikan batasan masuk agar cocok dengan nilai yang diteruskan ke nilai tersebut. Dalam contoh ini, nilainya adalah 150dp:

Sama seperti Gambar 7, kecuali dengan pengubah ukuran yang menyesuaikan batasan yang masuk agar cocok dengan nilai yang diteruskan ke pengubah ukuran.
Gambar 8. Pengubah size menyesuaikan batasan ke 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 dalam:

Dua hierarki UI dan representasinya yang sesuai dalam container. Pada langkah pertama,
  pengubah ukuran menerima batasan penyertaan; Dalam tampilan kedua, pengubah ukuran akan menyesuaikan dengan
  yang terlalu besar semirip mungkin, sehingga menghasilkan batasan yang mengisi container.
Gambar 9. Pengubah size yang mengikuti batasan yang diteruskan hampir sebaik mungkin.

Perhatikan bahwa merangkai beberapa pengubah size tidak akan berfungsi. size pertama pengubah menetapkan batasan minimum dan maksimum ke nilai tetap. Meskipun pengubah ukuran kedua meminta ukuran yang lebih kecil atau lebih besar, pengubah tersebut masih harus mematuhi batas yang tepat yang diteruskan, sehingga tidak akan mengganti nilai tersebut:

Rantai dua pengubah ukuran dalam hierarki UI dan representasinya dalam penampung,
  yang merupakan hasil dari nilai pertama yang diteruskan, bukan nilai kedua.
Gambar 10. Rantai dua pengubah size, dengan nilai kedua yang diteruskan (50dp) tidak mengganti nilai pertama (100dp).

Pengubah requiredSize

Gunakan pengubah requiredSize, bukan size, jika Anda memerlukan 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 berada di tengah ruang yang tersedia:

Ukuran dan pengubah requiredSize dirantai dalam hierarki UI, dan atribut
  di dalam container. Batasan pengubah requiredSize mengganti batasan pengubah
  ukuran.
Gambar 11. Pengubah 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 tinggi tidak ditentukan. Demikian pula, dengan pengubah height, Anda dapat menyetel tinggi tetap, tetapi membiarkan lebar belum ditentukan:

Dua hierarki UI, satu dengan pengubah lebar dan representasi penampung, dan yang lainnya
  dengan pengubah tinggi dan representasinya.
Gambar 12. Pengubah width dan pengubah height menyetel lebar tetap dan tingginya.

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.

Hierarki UI dengan pengubah sizeIn dengan lebar dan tinggi minimum dan maksimum yang ditetapkan,
  dan representasinya di dalam container.
Gambar 13. Pengubah sizeIn dengan minWidth, maxWidth, minHeight, dan maxHeight ditetapkan.

Contoh

Bagian ini menunjukkan 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:

  • Pengubah fillMaxSize mengubah batasan untuk menetapkan lebar dan tinggi minimum hingga nilai maksimum — lebar 300dp dan 200dp tingginya.
  • Meskipun ingin menggunakan ukuran 50dp, pengubah size tetap memerlukan untuk mematuhi batasan minimum yang masuk. Jadi, pengubah size akan juga menghasilkan batas batasan yang tepat dari 300 oleh 200, yang secara efektif mengabaikan nilai yang diberikan dalam pengubah size.
  • Image mengikuti batas ini dan melaporkan ukuran 300 dengan 200, yang diteruskan ke seluruh hierarki.

Image(
    painterResource(R.drawable.hero),
    contentDescription = null,
    Modifier
        .fillMaxSize()
        .wrapContentSize()
        .size(50.dp)
)

Cuplikan ini menghasilkan output berikut:

  • Pengubah fillMaxSize menyesuaikan batasan untuk menetapkan nilai minimum lebar dan tinggi hingga nilai maksimum — lebar 300dp dan 200dp inci tinggi.
  • Pengubah wrapContentSize mereset batasan minimum. Jadi, meskipun fillMaxSize menghasilkan batasan tetap, wrapContentSize meresetnya kembali ke batasan terbatas. Node berikut sekarang dapat menggunakan seluruh ruang penyimpanan lagi, atau lebih kecil dari keseluruhan ruang.
  • Pengubah size menetapkan batasan ke batas minimum dan maksimum 50.
  • Image me-resolve ke ukuran 50 dengan 50, dan pengubah size meneruskannya.
  • Pengubah wrapContentSize memiliki properti khusus. Dibutuhkan dan menempatkannya di tengah batas minimum yang tersedia yang yang diteruskan ke subnet tersebut. Dengan demikian, ukuran yang dikomunikasikan ke induknya sama dengan batas minimum yang diteruskan ke dalamnya.

Dengan hanya menggabungkan tiga pengubah, Anda dapat menentukan ukuran untuk 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 clip tidak mengubah batasan.
    • Pengubah padding menurunkan batasan maksimum.
    • Pengubah size menetapkan semua batasan ke 100dp.
    • Image mematuhi batasan tersebut dan melaporkan ukuran 100 dengan 100dp.
    • Pengubah padding menambahkan 10dp pada semua ukuran, sehingga meningkatkan lebar dan tinggi yang dilaporkan sebesar 20dp.
    • Sekarang dalam fase menggambar, pengubah clip bertindak pada kanvas 120 oleh 120dp. Jadi, kode ini membuat mask lingkaran dengan ukuran tersebut.
    • Pengubah padding kemudian menyisipkan kontennya dengan 10dp pada semua ukuran, sehingga menurunkan ukuran kanvas menjadi 100 dengan 100dp.
    • Image digambar di kanvas tersebut. Gambar dipangkas berdasarkan lingkaran asli 120dp, sehingga outputnya adalah hasil non-bulat.