Bagikan melalui


Ringkasan Bab 26. Tata letak kustom

Catatan

Buku ini diterbitkan pada musim semi 2016, dan belum diperbarui sejak saat itu. Ada banyak dalam buku yang tetap berharga, tetapi beberapa materi sudah kedaluarsa, dan beberapa topik tidak lagi sepenuhnya benar atau lengkap.

Xamarin.Forms termasuk beberapa kelas yang berasal dari Layout<View>:

  • StackLayout,
  • Grid,
  • AbsoluteLayout, dan
  • RelativeLayout.

Bab ini menjelaskan cara membuat kelas Anda sendiri yang berasal dari Layout<View>.

Gambaran umum tata letak

Tidak ada sistem terpusat Xamarin.Forms yang menangani tata letak. Setiap elemen bertanggung jawab untuk menentukan ukurannya sendiri, dan bagaimana merender dirinya sendiri dalam area tertentu.

Orang tua dan anak-anak

Setiap elemen yang memiliki anak bertanggung jawab untuk memposisikan anak-anak itu sendiri. Ini adalah induk yang pada akhirnya menentukan ukuran anak-anaknya berdasarkan ukuran yang tersedia dan ukuran yang diinginkan anak.

Ukuran dan posisi

Tata letak dimulai di bagian atas pohon visual dengan halaman lalu dilanjutkan melalui semua cabang. Metode publik yang paling penting dalam tata letak Layout didefinisikan oleh VisualElement. Setiap elemen yang merupakan induk dari elemen lain memanggil Layout setiap anaknya untuk memberi anak ukuran dan posisi relatif terhadap dirinya sendiri dalam bentuk Rectangle nilai. Panggilan ini Layout menyebar melalui pohon visual.

Panggilan ke Layout diperlukan agar elemen muncul di layar, dan menyebabkan properti baca-saja berikut diatur. Mereka konsisten dengan yang Rectangle diteruskan ke metode :

  • Bounds dari jenis Rectangle
  • X dari jenis double
  • Y dari jenis double
  • Width dari jenis double
  • Height dari jenis double

Layout Sebelum panggilan, Height dan Width memiliki nilai tiruan –1.

Panggilan ke Layout juga memicu panggilan ke metode yang dilindungi berikut:

Terakhir, peristiwa berikut diaktifkan:

Metode OnSizeAllocated ini ditimpa oleh Page dan Layout, yang merupakan satu-satunya kelas dalam Xamarin.Forms yang dapat memiliki anak. Panggilan metode yang ditimpa

LayoutChildren kemudian memanggil Layout untuk setiap anak elemen. Jika setidaknya satu anak memiliki pengaturan baru Bounds , maka peristiwa berikut diaktifkan:

Batasan dan permintaan ukuran

Untuk LayoutChildren memanggil Layout semua anaknya dengan cerdas, itu harus tahu ukuran yang disukai atau diinginkan untuk anak-anak. Oleh karena itu panggilan ke Layout untuk setiap anak umumnya didahului oleh panggilan ke

Setelah buku diterbitkan, GetSizeRequest metode tidak digunakan lagi dan diganti dengan

Metode ini Measure mengakomodasi Margin properti dan menyertakan argumen jenis MeasureFlag, yang memiliki dua anggota:

Untuk banyak elemen, GetSizeRequest atau Measure mendapatkan ukuran asli elemen dari perendernya. Kedua metode memiliki parameter untuk batasan lebar dan tinggi. Misalnya, Label akan menggunakan batasan lebar untuk menentukan cara membungkus beberapa baris teks.

Keduanya GetSizeRequestdan Measure mengembalikan nilai jenis SizeRequest, yang memiliki dua properti:

Sangat sering kedua nilai ini sama, dan Minimum nilai biasanya dapat diabaikan.

VisualElement juga mendefinisikan metode yang dilindungi yang mirip GetSizeRequest dengan yang disebut dari GetSizeRequest:

Metode tersebut sekarang tidak digunakan lagi dan diganti dengan:

Setiap kelas yang berasal dari Layout atau Layout<T> harus mengambil alih OnSizeRequest atau OnMeasure. Di sinilah kelas tata letak menentukan ukurannya sendiri, yang umumnya didasarkan pada ukuran anak-anaknya, yang diperolehnya dengan memanggil GetSizeRequest atau Measure pada anak-anak. Sebelum dan sesudah memanggil OnSizeRequest atau OnMeasure, GetSizeRequest atau Measure membuat penyesuaian berdasarkan properti berikut:

Batasan tak terbatas

Argumen batasan yang diteruskan ke GetSizeRequest (atau Measure) dan OnSizeRequest (atau OnMeasure) bisa tak terbatas (yaitu, nilai Double.PositiveInfinity). Namun, yang SizeRequest dikembalikan dari metode ini tidak boleh berisi dimensi tak terbatas.

Batasan tak terbatas menunjukkan bahwa ukuran yang diminta harus mencerminkan ukuran alami elemen. Panggilan GetSizeRequest vertikal StackLayout (atau Measure) pada anak-anaknya dengan batasan tinggi tak terbatas. Tata letak tumpukan horizontal memanggil GetSizeRequest (atau Measure) pada turunannya dengan batasan lebar tak terbatas. AbsoluteLayout Panggilan GetSizeRequest (atau Measure) pada anak-anaknya dengan batasan lebar dan tinggi tak terbatas.

Mengintip di dalam proses

ExploreChildSize menampilkan batasan dan ukuran informasi permintaan untuk tata letak sederhana.

Berasal dari Tampilan Tata Letak<>

Kelas tata letak kustom berasal dari Layout<View>. Ini memiliki dua tanggung jawab:

  • Ambil alih OnMeasure untuk memanggil Measure semua anak tata letak. Mengembalikan ukuran yang diminta untuk tata letak itu sendiri
  • Ambil alih LayoutChildren untuk memanggil Layout semua anak tata letak

Atau forforeach perulangan dalam penimpaan ini harus melewati anak mana pun yang propertinya IsVisible diatur ke false.

Panggilan ke OnMeasure tidak dijamin. OnMeasure tidak akan dipanggil jika induk tata letak mengatur ukuran tata letak (misalnya, tata letak yang mengisi halaman). Untuk alasan ini, LayoutChildren tidak dapat mengandalkan ukuran anak yang diperoleh selama OnMeasure panggilan. Sangat sering, LayoutChildren harus dengan sendirinya memanggil Measure anak-anak tata letak, atau Anda dapat menerapkan semacam logika penembolokan ukuran (untuk dibahas nanti).

Contoh yang mudah

Sampel VerticalStackDemo berisi kelas yang disederhanakan VerticalStack dan demonstrasi penggunaannya.

Penempatan vertikal dan horizontal disederhanakan

Salah satu pekerjaan yang VerticalStack harus dilakukan terjadi selama penimpaan LayoutChildren . Metode ini menggunakan properti anak HorizontalOptions untuk menentukan cara memposisikan anak dalam slotnya di VerticalStack. Anda dapat memanggil metode Layout.LayoutChildIntoBoundingRectstatis . Metode ini memanggil Measure anak dan menggunakan properti dan VerticalOptions untuk HorizontalOptions memosisikan anak dalam persegi panjang yang ditentukan.

Pembatalan

Seringkali perubahan properti elemen memengaruhi bagaimana elemen tersebut muncul dalam tata letak. Tata letak harus divalidasi untuk memicu tata letak baru.

VisualElement mendefinisikan metode InvalidateMeasureyang dilindungi , yang umumnya disebut oleh handler yang diubah properti dari properti yang dapat diikat yang perubahannya memengaruhi ukuran elemen. Metode ini InvalidateMeasure menembakkan MeasureInvalidated peristiwa.

Kelas Layout mendefinisikan metode yang dilindungi serupa bernama InvalidateLayout, yang Layout harus dipanggil turunan untuk setiap perubahan yang memengaruhi bagaimana posisi dan ukuran anak-anaknya.

Beberapa aturan untuk tata letak pengkodian

  1. Properti yang ditentukan oleh Layout<T> turunan harus didukung oleh properti yang dapat diikat, dan handler yang diubah properti harus memanggil InvalidateLayout.

  2. Layout<T> Turunan yang menentukan properti yang dapat diikat terlampir harus mengambil alih OnAdded untuk menambahkan handler yang diubah properti ke turunannya dan OnRemoved untuk menghapus handler tersebut. Handler harus memeriksa perubahan dalam properti yang dapat diikat terlampir ini dan merespons dengan memanggil InvalidateLayout.

  3. Turunan Layout<T> yang mengimplementasikan cache ukuran anak harus mengambil alih InvalidateLayout dan OnChildMeasureInvalidated dan menghapus cache ketika metode ini dipanggil.

Tata letak dengan properti

Kelas WrapLayout dalam Xamarin.FormsBook.Toolkit mengasumsikan bahwa semua anaknya berukuran sama, dan membungkus anak-anak dari satu baris (atau kolom) ke baris berikutnya. Ini mendefinisikan Orientation properti seperti StackLayout, dan ColumnSpacing properti RowSpacing seperti Grid, dan cache ukuran anak.

Sampel PhotoWrap dimasukkan WrapLayout ke dalam ScrollView untuk menampilkan foto stok.

Tidak ada dimensi yang tidak dibatasi yang diizinkan!

Di UniformGridLayoutXamarin.Formspustaka Book.Toolkit dimaksudkan untuk menampilkan semua anak-anaknya dalam dirinya sendiri. Oleh karena itu, tidak dapat berurusan dengan dimensi yang tidak dibatasi dan menimbulkan pengecualian jika ada yang ditemui.

Sampel PhotoGrid menunjukkan UniformGridLayout:

Cuplikan layar tiga kali Dari Photo Grid

Anak-anak yang tumpang tindih

Turunan Layout<T> dapat tumpang tindih dengan anak-anaknya. Namun, anak-anak dirender dalam urutan mereka dalam Children koleksi, dan bukan urutan di mana metode mereka Layout dipanggil.

Kelas Layout menentukan dua metode yang memungkinkan Anda memindahkan anak dalam koleksi:

  • LowerChild untuk memindahkan anak ke awal koleksi
  • RaiseChild untuk memindahkan anak ke akhir koleksi

Untuk anak-anak yang tumpang tindih, anak-anak di akhir koleksi secara visual muncul di atas anak-anak di awal koleksi.

Kelas OverlapLayout di Xamarin.Formspustaka Book.Toolkit mendefinisikan properti terlampir untuk menunjukkan urutan render dan dengan demikian memungkinkan salah satu anaknya ditampilkan di atas yang lain. Sampel StudentCardFile menunjukkan hal ini:

Cuplikan layar tiga kali dari Student Card File Grid

Properti yang dapat diikat lebih terlampir

Kelas CartesianLayout dalam Xamarin.Formspustaka Book.Toolkit mendefinisikan properti yang dapat diikat terlampir untuk menentukan dua Point nilai dan nilai ketebalan dan memanipulasi BoxView elemen agar menyerupai garis.

Sampel UnitCube menggunakannya untuk menggambar kubus 3D.

Tata Letak dan Tata LetakTo

Turunan Layout<T> dapat memanggil LayoutTo daripada Layout menganimasikan tata letak. Kelas AnimatedCartesianLayout melakukan ini, dan sampel AnimatedUnitCube menunjukkannya.