Praktikum 1 dan 2
Praktikum Flutter: Layout Responsif & Navigasi Aplikasi
Artikel ini menjelaskan implementasi Praktikum 1 (Layout Responsif) dan Praktikum 2 (Navigasi Aplikasi) dengan Flutter.
Fitur utama meliputi responsive layout, image gallery sederhana, Navigator.push(), dan BottomNavigationBar.
📌 Praktikum 1 – Layout Responsif
Pada praktikum ini, siswa mempraktikkan cara membuat layout sederhana di Flutter dengan
Column,
Row,
Flexible,
dan LayoutBuilder.
Hasilnya berupa galeri gambar responsif seperti Pinterest.
- Menampilkan gambar dari internet (placeholder API)
- Menggunakan GridView agar responsif terhadap ukuran layar
- Memanfaatkan LayoutBuilder untuk menentukan jumlah kolom
📌 Praktikum 2 – Navigasi Aplikasi
Pada praktikum ini, siswa diminta menambahkan halaman kedua dengan
Navigator.push()
dan mencoba BottomNavigationBar untuk berpindah antar halaman.
- Tombol Navigasi: dari halaman utama menuju halaman kedua
- BottomNavigationBar: untuk berpindah antar tab (Home & Gallery)
- AppBar dengan Hamburger Menu: untuk opsi tambahan
💻 Kode Lengkap (main.dart)
Berikut adalah implementasi dalam satu file main.dart:
// Flutter code (disederhanakan untuk artikel)
import 'package:flutter/material.dart';
void main() {
runApp(const PraktikumApp());
}
class PraktikumApp extends StatelessWidget {
const PraktikumApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Praktikum 1 & 2",
debugShowCheckedModeBanner: false,
theme: ThemeData(primarySwatch: Colors.blue),
home: const MainPage(),
);
}
}
/// Halaman utama dengan BottomNavigationBar
class MainPage extends StatefulWidget {
const MainPage({super.key});
@override
State createState() => _MainPageState();
}
class _MainPageState extends State {
int _selectedIndex = 0;
final List _pages = [
const ResponsivePage(),
const SecondPage(),
];
void _onItemTapped(int index) {
setState(() => _selectedIndex = index);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: _pages[_selectedIndex],
bottomNavigationBar: BottomNavigationBar(
currentIndex: _selectedIndex,
selectedItemColor: Colors.blue,
onTap: _onItemTapped,
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: "Halaman 1",
),
BottomNavigationBarItem(
icon: Icon(Icons.image),
label: "Halaman 2",
),
],
),
);
}
}
/// Halaman 1 – Layout Responsif dengan gambar
class ResponsivePage extends StatelessWidget {
const ResponsivePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Praktikum 1 – Layout Responsif"),
actions: [
IconButton(
icon: const Icon(Icons.arrow_forward),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (_) => const SecondPage()),
);
},
),
],
),
body: LayoutBuilder(
builder: (context, constraints) {
bool isWide = constraints.maxWidth > 600;
return isWide
? Row(
children: [
Flexible(
flex: 2,
child: _buildImage(
"https://picsum.photos/400/600?random=1", "Bagian Kiri"),
),
Flexible(
flex: 3,
child: Column(
children: [
Expanded(
child: _buildImage(
"https://picsum.photos/600/300?random=2", "Bagian Atas"),
),
Expanded(
child: _buildImage(
"https://picsum.photos/600/300?random=3", "Bagian Bawah"),
),
],
),
),
],
)
: Column(
children: [
Flexible(
flex: 2,
child: _buildImage(
"https://picsum.photos/600/300?random=4", "Bagian Atas"),
),
Flexible(
flex: 3,
child: Row(
children: [
Expanded(
child: _buildImage(
"https://picsum.photos/300/400?random=5", "Kiri"),
),
Expanded(
child: _buildImage(
"https://picsum.photos/300/400?random=6", "Kanan"),
),
],
),
),
],
);
},
),
);
}
Widget _buildImage(String url, String label) {
return Stack(
fit: StackFit.expand,
children: [
Image.network(
url,
fit: BoxFit.cover,
errorBuilder: (context, error, stackTrace) =>
const Center(child: Icon(Icons.broken_image, size: 50)),
),
Container(
alignment: Alignment.bottomCenter,
padding: const EdgeInsets.all(8),
color: Colors.black54,
child: Text(
label,
style: const TextStyle(color: Colors.white, fontSize: 18),
),
),
],
);
}
}
/// Halaman 2 – Galeri gambar sederhana
class SecondPage extends StatelessWidget {
const SecondPage({super.key});
@override
Widget build(BuildContext context) {
final List images = List.generate(
10,
(index) => "https://picsum.photos/300/200?random=$index",
);
return Scaffold(
appBar: AppBar(title: const Text("Praktikum 2 – Halaman Kedua")),
body: GridView.builder(
padding: const EdgeInsets.all(8),
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, // 2 kolom
crossAxisSpacing: 8,
mainAxisSpacing: 8,
),
itemCount: images.length,
itemBuilder: (context, index) {
return Image.network(
images[index],
fit: BoxFit.cover,
errorBuilder: (context, error, stackTrace) =>
const Icon(Icons.broken_image, size: 50),
);
},
),
);
}
}
🛠️ Teknologi yang Digunakan
| Komponen | Fungsi |
|---|---|
| Column & Row | Membuat layout vertikal & horizontal |
| Flexible | Membuat widget lebih adaptif terhadap ruang |
| LayoutBuilder | Menentukan jumlah kolom secara responsif |
| Navigator.push() | Navigasi ke halaman kedua |
| BottomNavigationBar | Pindah antar halaman dengan tab |
✅ Kesimpulan
Dengan dua praktikum ini, siswa memahami dasar-dasar layout responsif sekaligus navigasi antar halaman di Flutter. Hasilnya adalah aplikasi sederhana yang menyerupai galeri gambar dengan kemampuan berpindah halaman melalui tombol dan BottomNavigationBar.
Hasil Lihat Disini
Komentar
Posting Komentar