layoutalignmentrowcolumnPemula4 mnt baca

MainAxis & CrossAxis Alignment

Atur posisi anak: start, center, end, spaceBetween, spaceEvenly.

Analogi: Tukang Parkir di Lapangan Kosong

Bayangkan lapangan parkir yang kosong dan tiga mobil datang. Kamu bisa menyuruh semuanya rapat di kiri (start), berkumpul di tengah (center), rapat di kanan (end), atau menyebar dengan jarak yang sama rata (spaceEvenly). MainAxisAlignment dan CrossAxisAlignment adalah "tukang parkir" untuk widget: mereka mengatur di mana anak-anak Row atau Column berdiri ketika ada ruang sisa.

Kenapa Alignment Ada?

Secara default, Row dan Column menumpuk anaknya rapat di awal (start) dan membiarkan sisa ruang kosong begitu saja. Tanpa alignment, kamu harus menghitung padding manual supaya sebuah tombol benar-benar di tengah, dan itu rapuh: ganti ukuran layar, hitungannya rusak.

Alignment menyelesaikan masalah ini dengan mendeklarasikan niat: "tengah", "rata kiri-kanan", "beri jarak sama". Flutter yang menghitung pikselnya di semua ukuran layar, jadi niatmu tetap benar di HP kecil maupun tablet besar.

Dua Sumbu: Main Axis dan Cross Axis

Setiap Row atau Column punya dua sumbu:

  • Main axis: sumbu searah susunan. Horizontal untuk Row, vertikal untuk Column.
  • Cross axis: sumbu yang tegak lurus. Vertikal untuk Row, horizontal untuk Column.

mainAxisAlignment mengatur posisi di sepanjang main axis, crossAxisAlignment mengatur posisi di sepanjang cross axis. Keduanya bekerja bersamaan:

dart
Column(
  mainAxisAlignment: MainAxisAlignment.center, // vertikal: tengah
  crossAxisAlignment: CrossAxisAlignment.start, // horizontal: rata kiri
  children: const [Text('A'), Text('B')],
)

Cara menghafalnya: untuk Column, main berarti vertikal. Untuk Row, main berarti horizontal. Sisanya tinggal mengikuti.

Nilai MainAxisAlignment

  • start: semua anak rapat di awal.
  • center: semua anak berkumpul di tengah.
  • end: semua anak rapat di akhir.
  • spaceBetween: anak pertama menempel di awal, anak terakhir menempel di akhir, sisanya diberi jarak rata di antaranya.
  • spaceAround: jarak rata di antara anak, dengan setengah jarak di kedua tepi.
  • spaceEvenly: semua jarak, termasuk di tepi, sama persis.

Contoh yang paling sering dipakai di dunia nyata: baris total belanja.

dart
Row(
  mainAxisAlignment: MainAxisAlignment.spaceBetween,
  children: const [
    Text('Total Bayar'),
    Text('Rp75.000', style: TextStyle(fontWeight: FontWeight.bold)),
  ],
)

"Total Bayar" menempel kiri, harga menempel kanan, tanpa kamu menghitung lebar layar sama sekali. Ganti HP, tetap rapi.

Contoh Realistis: Form Login yang Rapi

Sekarang gabungkan kedua sumbu. Formulir login yang baik biasanya vertikal di tengah layar, tapi setiap field melebar penuh supaya tombol dan input sama lebarnya:

dart
Padding(
  padding: const EdgeInsets.all(24),
  child: Column(
    mainAxisAlignment: MainAxisAlignment.center,
    crossAxisAlignment: CrossAxisAlignment.stretch,
    children: [
      const Text(
        'Selamat Datang',
        style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
      ),
      const SizedBox(height: 24),
      const TextField(decoration: InputDecoration(labelText: 'Email')),
      const SizedBox(height: 12),
      const TextField(
        decoration: InputDecoration(labelText: 'Password'),
        obscureText: true,
      ),
      const SizedBox(height: 24),
      ElevatedButton(onPressed: () {}, child: const Text('Masuk')),
    ],
  ),
)

mainAxisAlignment.center menengahkan formulir secara vertikal, crossAxisAlignment.stretch memaksa setiap field melebar penuh secara horizontal. Hasilnya rapi tanpa satu pun angka lebar manual.

Catatan teknis: MainAxisAlignment hanya berpengaruh kalau ada ruang sisa. Row yang lebarnya pas-pasan dengan total lebar anaknya tidak akan menunjukkan perbedaan apa pun, nilai apa pun yang kamu pasang. Kalau alignment "tidak bekerja", cek dulu apakah ada ruang sisa untuk didistribusikan.

Nilai CrossAxisAlignment

  • start: rata di awal cross axis (atas untuk Row, kiri untuk Column).
  • center: tengah (ini nilai default untuk Column).
  • end: rata di akhir cross axis.
  • stretch: anak dipaksa selebar (atau setinggi) ruang cross axis yang tersedia.

Kesalahan Umum Pemula

1. Alignment tidak "berpengaruh" karena tidak ada ruang sisa

Salah: Column memakai mainAxisSize: MainAxisSize.min lalu heran kenapa center tidak bekerja. Dengan min, Column hanya setinggi anak-anaknya, jadi tidak ada ruang sisa untuk didistribusikan.

dart
// SALAH: tidak ada ruang sisa, center tidak berpengaruh
Column(
  mainAxisSize: MainAxisSize.min,
  mainAxisAlignment: MainAxisAlignment.center,
  children: const [Text('A'), Text('B')],
)

Benar: biarkan Column mengisi ruang yang tersedia (default-nya max), atau bungkus dengan widget yang memberi ruang seperti Center atau Expanded.

dart
// BENAR: Column memenuhi tinggi layar, center bekerja
Column(
  mainAxisAlignment: MainAxisAlignment.center,
  children: const [Text('A'), Text('B')],
)

2. Tertukar antara main axis dan cross axis

Salah: memakai crossAxisAlignment di Row sambil berharap anak-anak tersebar horizontal. Di Row, cross axis itu vertikal, jadi yang diatur adalah posisi atas-tengah-bawah, bukan kiri-kanan.

dart
// SALAH: ini mengatur posisi vertikal, bukan penyebaran horizontal
Row(
  crossAxisAlignment: CrossAxisAlignment.center,
  children: const [Text('A'), Text('B')],
)

Benar: penyebaran horizontal di Row adalah urusan mainAxisAlignment.

dart
// BENAR
Row(
  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  children: const [Text('A'), Text('B')],
)

3. Heran kenapa teks di Column tidak rata kiri

Nilai default crossAxisAlignment untuk Column adalah center, jadi semua anak otomatis di tengah secara horizontal. Kalau maunya rata kiri seperti artikel, pasang eksplisit:

dart
// BENAR: teks rata kiri
Column(
  crossAxisAlignment: CrossAxisAlignment.start,
  children: const [Text('Judul'), Text('Isi artikel...')],
)

Ini salah satu "misteri" paling umum di minggu pertama belajar Flutter, dan jawabannya selalu baris yang sama: crossAxisAlignment: CrossAxisAlignment.start.

Tantangan

Baris total belanja

Buat Row dengan mainAxisAlignment.spaceBetween berisi Text 'Total Bayar' dan Text 'Rp75.000' tebal. Bungkus dalam Padding horizontal 16.