Metode build adalah bagian dari widget yang menerjemahkan konfigurasinya menjadi deskripsi tampilan. Topik ini membahas kontrak yang wajib dipenuhi metode build, kejadian yang memicu pemanggilannya kembali, alur constraint yang menentukan ukuran setiap widget, dan kebiasaan yang menjaga biaya rebuild tetap rendah.
Kontrak metode build#
Metode build mengembalikan pohon widget yang menggambarkan tampilan saat ini, dan pengerjaannya wajib murni (pure), yaitu keluarannya hanya ditentukan oleh masukan tanpa mengubah apa pun di luar dirinya. Pemanggilan build tidak boleh menulis berkas, mengirim permintaan jaringan, mengubah state, atau memicu pemanggilan build lain. Framework dapat memanggil build kapan pun diperlukan, sehingga hasilnya harus selalu sama selama state dan konfigurasinya sama.
Parameter BuildContext menunjuk posisi widget pada pohon dan digunakan untuk mencari data milik widget di atasnya pada pohon, misalnya tema melalui Theme.of(context). Melalui objek ini, sebuah widget dapat menyesuaikan diri dengan lingkungannya tanpa menerima data tersebut lewat constructor.
// tidak-dijalankan
@override
Widget build(BuildContext context) {
final sisa = totalTugas - jumlahSelesai;
return Text('$sisa tugas belum selesai');
}Metode pada contoh hanya menghitung dan mengembalikan widget. Tidak ada state yang diubah dan tidak ada pekerjaan yang menyimpang dari pembuatan deskripsi tampilan. Pola seperti ini aman dipanggil berulang kali sebanyak apa pun.
Kapan rebuild terjadi#
Pemanggilan build terjadi saat pertama kali widget memasuki pohon, kemudian berulang setiap kali terjadi perubahan yang memengaruhi widget tersebut. Tiga kejadian yang paling sering memicunya adalah setState pada State milik widget, pembuatan widget baru oleh widget induk dengan konfigurasi yang berbeda, dan berubahnya data yang diambil melalui BuildContext, misalnya tema atau ukuran layar.
// tidak-dijalankan
class KartuNilai extends StatelessWidget {
const KartuNilai({super.key, required this.nilai});
final int nilai;
@override
Widget build(BuildContext context) {
return Text('Nilai: $nilai');
}
}Apabila widget induk membuat KartuNilai dengan nilai 80 setelah sebelumnya 75, build pada KartuNilai dipanggil kembali dengan konfigurasi yang baru. Widget tersebut tidak melakukan apa pun untuk memicunya, karena inisiatif rebuild selalu berada pada pemilik state atau pada widget induk.
Frekuensi rebuild yang tinggi adalah perilaku normal, bukan tanda kesalahan. Framework memang dirancang untuk memanggil build berkali-kali dalam satu detik, misalnya saat animasi berjalan atau saat pengguna mengetik. Yang perlu dikelola bukan frekuensinya, melainkan jumlah pekerjaan yang dilakukan pada setiap pemanggilan.
Alur constraint: turun, ukuran naik, posisi ditetapkan#
Ukuran sebuah widget tidak sepenuhnya ditentukan oleh widget itu sendiri. Setiap widget menerima constraint, yaitu batasan lebar dan tinggi berupa rentang minimum serta maksimum, dari induknya, kemudian memilih ukurannya di dalam rentang tersebut. Hasil pilihan itu dilaporkan kembali ke induk, dan induk yang menetapkan posisi anaknya dalam ruang yang tersedia.
Alurnya ringkas menjadi tiga kaidah: constraint turun dari induk ke anak, ukuran naik dari anak ke induk, dan posisi ditetapkan induk. Diagram berikut menggambarkan ketiganya pada sebuah Row dengan dua anak.
Sebagai contoh, Row menerima constraint dari induknya, misalnya lebar maksimum 400 piksel logis, lalu meneruskan batasan yang sesuai kepada anak-anaknya. Text memilih lebar sesuai panjang teks dan gaya hurufnya, melaporkan hasilnya ke atas, dan Row menyusun kedua anak berjajar sekaligus menetapkan posisi masing-masing. Seluruh proses berjalan dalam satu lintasan (single pass), sehingga layout dengan ratusan widget tetap cepat. Istilah piksel logis (logical pixel) menyebut satuan ukuran Flutter yang menyesuaikan diri dengan kerapatan layar.
Menjaga biaya rebuild tetap rendah#
Karena build dipanggil berkali-kali, pekerjaan apa pun di dalamnya ikut diulang pada setiap pemanggilan. Kebiasaan pertama adalah menandai subpohon yang tidak pernah berubah dengan const, sehingga instance yang sama digunakan ulang antar-rebuild dan pemeriksaan perubahan dapat berhenti pada batas tersebut. Kebiasaan kedua adalah memecah widget besar menjadi widget kecil, sehingga perubahan state hanya memicu pembangunan ulang pada sebagian kecil pohon. Kebiasaan ketiga adalah memindahkan pengolahan data yang berat ke luar build, misalnya ke constructor atau ke tempat perubahan state terjadi.
// tidak-dijalankan
Column(
children: [
const Text('Statistik nilai ujian', style: TextStyle(fontSize: 20)),
Text('Rata-rata kelas: $rataRata'),
],
)Baris pertama bertanda const, sehingga instance Text yang sama digunakan ulang meskipun rataRata berubah dan build pada Column dipanggil kembali. Baris kedua memang harus dibuat baru karena isinya bergantung pada data. Penghematan seperti ini terasa kecil pada satu widget, tetapi berlipat pada pohon yang besar.
Kesalahan umum#
- Melakukan pekerjaan berat di dalam build. Mengurutkan daftar yang panjang atau mengurai data besar pada setiap pemanggilan
buildmenghabiskan waktu satu frame. Perbaikannya, hitung hasilnya sekali di luarbuild, misalnya saat data diterima, lalu simpan untuk digunakan berulang. - Menghitung ukuran layar secara manual. Membagi lebar layar dengan angka tetap untuk menentukan lebar anak meniru kerja constraint tanpa memperoleh keunggulannya. Perbaikannya, susun dengan widget layout dan biarkan alur constraint turun serta ukuran naik yang menentukan hasilnya.
Ringkasan#
buildwajib murni: keluarannya hanya bergantung pada state dan konfigurasi, tanpa efek samping.- Rebuild dipicu oleh
setState, konfigurasi baru dari widget induk, dan perubahan data yang diambil melaluiBuildContext. - Layout mengikuti tiga kaidah: constraint turun dari induk ke anak, ukuran naik dari anak ke induk, dan posisi ditetapkan induk.
constdan pemecahan widget mempersempit cakupan rebuild.
Referensi#
- Understanding constraints — Flutter — Penjelasan resmi alur constraint turun, ukuran naik, dan posisi yang ditetapkan induk.
- StatelessWidget class — Flutter API
— Dokumentasi metode
builddan kontrak pemanggilannya. - BuildContext class — Flutter API — Dokumentasi objek konteks beserta penggunaannya untuk mengakses data milik widget di atasnya pada pohon.