📚 Materi: Konsep Dasar Layout Responsif, Grid, Media Queries, dan Navigasi di Flutter
🎯 Tujuan Pembelajaran
Setelah mengikuti materi ini, siswa diharapkan dapat:
-
Memahami konsep layout responsif pada aplikasi mobile.
-
Menggunakan Grid dan widget layout lain untuk menata tampilan.
-
Menerapkan MediaQuery untuk menyesuaikan UI dengan ukuran layar.
-
Mengimplementasikan navigasi antar-halaman (single screen & multi screen).
🧠 1. Konsep Dasar Layout Responsif
Layout responsif = tampilan menyesuaikan ukuran layar (HP kecil, tablet, laptop).
Dalam Flutter:
-
Gunakan MediaQuery untuk mengetahui ukuran layar.
-
Gunakan widget yang fleksibel seperti:
-
Expanded
-
Flexible
-
LayoutBuilder
-
📌 Poin Penting:
-
Hindari ukuran fix (
width: 300) jika tidak perlu. -
Gunakan
MediaQuery.of(context).size.width * 0.5→ agar proporsional. -
Gunakan widget seperti
FlexibleatauExpandeduntuk menyesuaikan otomatis.
🧩 2. Grid Layout
Grid adalah cara menampilkan item secara kotak-kotak seperti galeri foto.
Widget Utama:
-
GridView.count -
GridView.builder
Contoh Grid sederhana:
GridView.count(
crossAxisCount: 2, // jumlah kolom
children: List.generate(6, (index) {
return Card(
color: Colors.blueAccent,
child: Center(child: Text('Item $index')),
);
}),
)
🖥 3. MediaQuery
Digunakan untuk mendapatkan informasi layar:
-
MediaQuery.of(context).size.width→ lebar layar -
MediaQuery.of(context).size.height→ tinggi layar -
MediaQuery.of(context).orientation→ portrait/landscape
Contoh:
double screenWidth = MediaQuery.of(context).size.width;
if (screenWidth < 600) {
// Tampilan untuk HP kecil
} else {
// Tampilan untuk tablet
}
🧭 4. Jenis Navigasi
Navigasi menghubungkan halaman (screen) dalam aplikasi.
Jenis navigasi di Flutter:
-
Navigator.push() & Navigator.pop()
– Navigasi standar, berpindah halaman. -
BottomNavigationBar
– Navigasi dengan tab bawah. -
Drawer Navigation
– Menu navigasi yang bisa digeser dari kiri.
🖊 Contoh Lengkap di zapp.run
Salin kode berikut ke https://zapp.run dan jalankan:
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Layout Responsif & Navigasi',
debugShowCheckedModeBanner: false,
home: const HomePage(),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width;
return Scaffold(
appBar: AppBar(title: const Text("Layout Responsif")),
drawer: Drawer(
child: ListView(
children: [
const DrawerHeader(
decoration: BoxDecoration(color: Colors.blue),
child: Text("Menu Navigasi", style: TextStyle(color: Colors.white)),
),
ListTile(
leading: const Icon(Icons.home),
title: const Text("Home"),
onTap: () => Navigator.pop(context),
),
ListTile(
leading: const Icon(Icons.grid_view),
title: const Text("Grid Page"),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (_) => const GridPage()),
);
},
),
],
),
),
body: Center(
child: Container(
width: screenWidth * 0.8, // responsif: 80% dari layar
padding: const EdgeInsets.all(16),
color: Colors.blue[50],
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Text("Halo! Ini layout responsif",
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
const SizedBox(height: 10),
ElevatedButton(
child: const Text("Buka Grid Page"),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (_) => const GridPage()),
);
},
),
],
),
),
),
bottomNavigationBar: BottomNavigationBar(
items: const [
BottomNavigationBarItem(icon: Icon(Icons.home), label: "Home"),
BottomNavigationBarItem(icon: Icon(Icons.settings), label: "Settings"),
],
),
);
}
}
class GridPage extends StatelessWidget {
const GridPage({super.key});
@override
Widget build(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width;
final crossAxisCount = screenWidth < 600 ? 2 : 4; // responsif
return Scaffold(
appBar: AppBar(title: const Text("Grid Page")),
body: GridView.count(
crossAxisCount: crossAxisCount,
padding: const EdgeInsets.all(10),
children: List.generate(8, (index) {
return Card(
elevation: 2,
child: Center(child: Text("Item $index")),
);
}),
),
);
}
}
🏁 Aktivitas Praktikum
-
Jalankan kode di atas di zapp.run.
-
Ubah
crossAxisCountdiGridPagemenjadi nilai berbeda dan lihat perubahan tampilan. -
Tambahkan halaman baru (
AboutPage) dan navigasikan dari Drawer. -
Ubah
MediaQuerysehingga jika layar lebar, warna latar berubah menjadi hijau.
❓ Pertanyaan Pemantik
-
Apa perbedaan
crossAxisCount: 2dancrossAxisCount: 4? -
Bagaimana aplikasi menyesuaikan layout ketika layar diputar (portrait → landscape)?
-
Mengapa kita perlu
MediaQueryuntuk membuat tampilan responsif?
🎯 Coding Challenge: Layout Responsif & Navigasi
📝 Instruksi
-
Salin kode program yang sudah diberikan ke zapp.run atau VS Code + emulator.
-
Jalankan program dan amati hasil awalnya.
-
Selesaikan tantangan di bawah ini satu per satu.
💡 Challenge 1: Ubah Warna Berdasarkan Ukuran Layar
Gunakan MediaQuery untuk membuat warna background container berbeda:
-
Jika
screenWidth < 600→ warna biru muda. -
Jika
screenWidth ≥ 600→ warna hijau muda.
💡 Hint: Gunakan ternary operator:
color: screenWidth < 600 ? Colors.blue[50] : Colors.green[50],
💡 Challenge 2: Tambah Item Grid Dinamis
Ubah List.generate(8, ...) menjadi List.generate(20, ...) dan lihat bagaimana grid menyesuaikan layout.
Kemudian ubah crossAxisCount menjadi 3 jika lebar layar antara 600–900.
💡 Hint: Gunakan if-else:
int crossAxisCount;
if (screenWidth < 600) {
crossAxisCount = 2;
} else if (screenWidth < 900) {
crossAxisCount = 3;
} else {
crossAxisCount = 4;
}
💡 Challenge 3: Tambah Halaman Baru
Buat halaman baru bernama AboutPage yang menampilkan teks:
"Aplikasi ini dibuat oleh [Nama Kamu]"
Tambahkan menu About di Drawer untuk navigasi ke halaman ini.
💡 Challenge 4: BottomNavigationBar Aktif
-
Tambahkan aksi pada
BottomNavigationBarsehingga jika icon "Settings" ditekan, muncul halaman baruSettingsPage. -
Isi
SettingsPagedengan teks sederhana "Pengaturan Aplikasi".
💡 Challenge 5 (Bonus): Mode Gelap
Tambahkan tombol di halaman Home untuk mengaktifkan Dark Mode.
💡 Hint: Gunakan ThemeMode.dark atau ThemeMode.light pada MaterialApp.
📸 Tugas Pengumpulan
-
Screenshot tampilan aplikasi setelah Challenge 1 & 2.
-
Screenshot halaman About & Settings.
-
Jika bisa, rekam layar saat menekan tombol navigasi & lihat perubahan grid.
Dengan challenge ini, siswa diharapkan bisa bereksperimen, berpikir kreatif, dan memahami kenapa MediaQuery & navigasi penting.
Salam : Redaksi







Tidak ada komentar:
Posting Komentar