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.

Komentar

Postingan populer dari blog ini

Jenis-jenis sistem operasi mobile

flutter todo list app

Aplikasi Manajemen Barang Pinjaman dengan Flutter + Fitur Upload Gambar