flutterresponsiflayoutMahir3 mnt baca

Layout Responsif: Adaptif Berbagai Ukuran Layar

Buat UI yang rapi di HP kecil, HP besar, dan tablet dengan MediaQuery, LayoutBuilder, dan breakpoint.

Masalah fragmentasi layar

Android punya ribuan ukuran layar. Layout yang pas di HP-mu bisa overflow di HP kecil atau terlihat kosong melompong di tablet. Desain responsif berarti layout menyesuaikan ruang yang tersedia, bukan mengasumsikan satu ukuran.

MediaQuery: baca ukuran layar

dart
@override
Widget build(BuildContext context) {
  final lebar = MediaQuery.of(context).size.width;
  final jumlahKolom = lebar < 600 ? 2 : lebar < 900 ? 3 : 4;

  return GridView.builder(
    gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
      crossAxisCount: jumlahKolom,
    ),
    itemCount: produk.length,
    itemBuilder: (context, i) => KartuProduk(produk: produk[i]),
  );
}

Pola breakpoint sederhana: di bawah 600 (HP) 2 kolom, 600-900 (HP besar/foldable) 3 kolom, di atas 900 (tablet) 4 kolom.

LayoutBuilder: responsif per widget

MediaQuery membaca ukuran layar penuh. LayoutBuilder membaca ukuran yang tersedia untuk widget itu sendiri, lebih tepat untuk komponen reusable:

dart
LayoutBuilder(
  builder: (context, constraints) {
    if (constraints.maxWidth < 400) {
      // Layar sempit: susun vertikal
      return Column(
        children: [GambarProduk(), InfoProduk()],
      );
    }
    // Layar lega: susun horizontal
    return Row(
      children: [GambarProduk(), Expanded(child: InfoProduk())],
    );
  },
)

Komponen ini otomatis menyesuaikan diri entah ditaruh di HP, di setengah layar tablet, atau di dialog.

OrientationBuilder

Untuk perbedaan portrait vs landscape yang drastis:

dart
OrientationBuilder(
  builder: (context, orientation) {
    final isLandscape = orientation == Orientation.landscape;
    return GridView.count(
      crossAxisCount: isLandscape ? 4 : 2,
      children: [...],
    );
  },
)

Hindari nilai piksel kaku

Ganti ukuran fixed dengan proporsi atau Expanded/Flexible. Daripada Container(width: 350), pakai FractionallySizedBox atau biarkan parent yang menentukan. Teks pakai FittedBox atau atur maxLines agar tidak overflow di layar kecil.

dart
// Buruk: kaku di semua layar
Container(width: 350, child: ...)

// Baik: mengikuti parent
SizedBox(
  width: double.infinity,
  child: Padding(
    padding: const EdgeInsets.symmetric(horizontal: 16),
    child: ...,
  ),
)

Catatan teknis: Memanggil MediaQuery.of(context) di widget yang rebuild karena animasi akan ikut rebuild setiap ada perubahan metrics, tapi itu jarang masalah. Yang lebih penting: test di minimal tiga ukuran (kecil 360px, standar 412px, tablet 800px) memakai device preview atau emulator berbeda. Bug responsif hampir tidak pernah ketahuan kalau cuma test di satu emulator.