Membangun Aplikasi Kuliner Nusantara dengan Login dan Navigasi Multi-Halaman

  Membangun Aplikasi Kuliner Nusantara dengan Login dan Navigasi Multi-Halaman


Pada pelajaran kali ini, kita belajar bagaimana membuat aplikasi kuliner Nusantara menggunakan Flutter, mulai dari membuat tampilan utama, navigasi antar halaman, hingga implementasi login sederhana di halaman profil.

Berikut hal-hal penting yang dipelajari:

  1. Struktur Aplikasi Flutter dengan StatefulWidget

    • Kita membuat aplikasi menggunakan StatefulWidget agar aplikasi bisa merespon perubahan data, seperti tema gelap/terang dan daftar favorit kuliner.

  2. Navigasi dengan BottomNavigationBar

    • Aplikasi memiliki 5 halaman: Beranda, Kuliner, Pencarian, Favorit, dan Profil.

    • Navigasi dilakukan menggunakan BottomNavigationBar, yang memungkinkan pengguna berpindah antar halaman dengan mudah.

  3. Menampilkan Data Kuliner dengan GridView

    • Daftar kuliner ditampilkan menggunakan GridView.builder.

    • Setiap item memiliki gambar dan nama, serta dapat ditandai sebagai favorit.

  4. Fitur Favorit

    • Pengguna dapat menandai kuliner favorit dengan ikon hati (Icons.favorite).

    • Daftar favorit tersimpan sementara selama aplikasi berjalan dan dapat dilihat di halaman Favorit.

  5. Pencarian Kuliner dengan TextField

    • Halaman pencarian menggunakan TextField dengan onSubmitted, sehingga ketika pengguna menekan Enter, hasil pencarian langsung ditampilkan.

    • Hasil pencarian ditampilkan dalam bentuk daftar (ListView) yang interaktif.

  6. Halaman Profil dengan Login Sederhana

    • Sebelum masuk ke halaman profil, pengguna harus mengisi nama dan email.

    • Setelah mengisi dan menekan Enter atau tombol Masuk, data akan ditampilkan di halaman profil.

    • Di halaman profil juga ada toggle untuk mode gelap/terang, serta opsi pengaturan dan keluar.


ini codinganya 

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

// ================= APP UTAMA =================
class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool _isDarkMode = false;

  void toggleTheme(bool value) {
    setState(() {
      _isDarkMode = value;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Kuliner Nusantara',
      debugShowCheckedModeBanner: false,
      theme: _isDarkMode
          ? ThemeData.dark().copyWith(
              appBarTheme: const AppBarTheme(backgroundColor: Colors.green),
            )
          : ThemeData.light().copyWith(
              appBarTheme: const AppBarTheme(backgroundColor: Colors.green),
            ),
      home: MainPage(
        isDarkMode: _isDarkMode,
        onThemeChanged: toggleTheme,
      ),
    );
  }
}

// ================= MAIN PAGE DENGAN NAVBAR =================
class MainPage extends StatefulWidget {
  final bool isDarkMode;
  final Function(bool) onThemeChanged;

  const MainPage({
    super.key,
    required this.isDarkMode,
    required this.onThemeChanged,
  });

  @override
  State<MainPage> createState() => _MainPageState();
}

class _MainPageState extends State<MainPage> {
  int _currentIndex = 0;

  // Daftar favorit
  List<Map<String, String>> favorit = [];

  // Toggle favorit
  void toggleFavorit(Map<String, String> item) {
    setState(() {
      if (favorit.contains(item)) {
        favorit.remove(item);
      } else {
        favorit.add(item);
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    final pages = [
      const HomePage(),
      KulinerPage(onFavoritChanged: toggleFavorit, favorit: favorit),
      SearchPage(onFavoritChanged: toggleFavorit, favorit: favorit),
      FavoritPage(favorit: favorit),
      ProfilPage(isDarkMode: widget.isDarkMode, onThemeChanged: widget.onThemeChanged),
    ];

    return Scaffold(
      body: pages[_currentIndex],
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _currentIndex,
        type: BottomNavigationBarType.fixed,
        onTap: (index) => setState(() => _currentIndex = index),
        items: const [
          BottomNavigationBarItem(icon: Icon(Icons.home), label: "Beranda"),
          BottomNavigationBarItem(icon: Icon(Icons.restaurant), label: "Kuliner"),
          BottomNavigationBarItem(icon: Icon(Icons.search), label: "Cari"),
          BottomNavigationBarItem(icon: Icon(Icons.favorite), label: "Favorit"),
          BottomNavigationBarItem(icon: Icon(Icons.person), label: "Profil"),
        ],
      ),
    );
  }
}

// ================= DATA KULINER =================
const List<Map<String, String>> kulinerList = [
  {"nama": "Rendang", "gambar": "assets/images/rendang.jpg"},
  {"nama": "Sate", "gambar": "assets/images/sate.jpg"},
  {"nama": "Pempek", "gambar": "assets/images/pempek.jpg"},
  {"nama": "Bakso", "gambar": "assets/images/bakso.jpg"},
  {"nama": "Rawon", "gambar": "assets/images/rawon.jpg"},
  {"nama": "Gudeg Jogja", "gambar": "assets/images/gudeg.jpg"},
];

// ================= HALAMAN BERANDA =================
class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Beranda")),
      body: Padding(
        padding: const EdgeInsets.all(12),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const Text(
              "Rekomendasi Kuliner",
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 10),
            Expanded(
              child: GridView.builder(
                gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 2,
                  crossAxisSpacing: 10,
                  mainAxisSpacing: 10,
                ),
                itemCount: kulinerList.length,
                itemBuilder: (context, index) {
                  return Card(
                    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
                    elevation: 4,
                    child: Column(
                      children: [
                        Expanded(
                          child: ClipRRect(
                            borderRadius: const BorderRadius.vertical(top: Radius.circular(12)),
                            child: Image.asset(
                              kulinerList[index]["gambar"]!,
                              fit: BoxFit.cover,
                              width: double.infinity,
                            ),
                          ),
                        ),
                        Padding(
                          padding: const EdgeInsets.all(8),
                          child: Text(
                            kulinerList[index]["nama"]!,
                            style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
                          ),
                        )
                      ],
                    ),
                  );
                },
              ),
            )
          ],
        ),
      ),
    );
  }
}

// ================= HALAMAN KULINER =================
class KulinerPage extends StatelessWidget {
  final Function(Map<String, String>) onFavoritChanged;
  final List<Map<String, String>> favorit;

  const KulinerPage({super.key, required this.onFavoritChanged, required this.favorit});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Kuliner Nusantara")),
      body: Padding(
        padding: const EdgeInsets.all(12),
        child: GridView.builder(
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 2,
            crossAxisSpacing: 10,
            mainAxisSpacing: 10,
          ),
          itemCount: kulinerList.length,
          itemBuilder: (context, index) {
            final item = kulinerList[index];
            final isFavorit = favorit.contains(item);

            return GestureDetector(
              onTap: () => onFavoritChanged(item),
              child: Card(
                shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
                elevation: 4,
                child: Column(
                  children: [
                    Expanded(
                      child: Stack(
                        children: [
                          ClipRRect(
                            borderRadius: const BorderRadius.vertical(top: Radius.circular(12)),
                            child: Image.asset(item["gambar"]!, fit: BoxFit.cover, width: double.infinity),
                          ),
                          Positioned(
                            top: 8,
                            right: 8,
                            child: Icon(isFavorit ? Icons.favorite : Icons.favorite_border, color: Colors.red),
                          ),
                        ],
                      ),
                    ),
                    Padding(
                      padding: const EdgeInsets.all(8),
                      child: Text(item["nama"]!, style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16)),
                    )
                  ],
                ),
              ),
            );
          },
        ),
      ),
    );
  }
}

// ================= HALAMAN PENCARIAN =================
class SearchPage extends StatefulWidget {
  final Function(Map<String, String>)? onFavoritChanged;
  final List<Map<String, String>>? favorit;

  const SearchPage({super.key, this.onFavoritChanged, this.favorit});

  @override
  State<SearchPage> createState() => _SearchPageState();
}

class _SearchPageState extends State<SearchPage> {
  String query = "";
  List<Map<String, String>> results = [];

  void search(String value) {
    setState(() {
      query = value;
      results = kulinerList
          .where((item) => item["nama"]!.toLowerCase().contains(query.toLowerCase()))
          .toList();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Cari Kuliner")),
      body: Padding(
        padding: const EdgeInsets.all(12),
        child: Column(
          children: [
            TextField(
              decoration: InputDecoration(
                hintText: "Cari kuliner...",
                prefixIcon: const Icon(Icons.search),
                border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
              ),
              onSubmitted: (value) => search(value), // Tekan Enter
            ),
            const SizedBox(height: 12),
            Expanded(
              child: results.isEmpty
                  ? const Center(child: Text("Hasil pencarian kosong"))
                  : ListView.builder(
                      itemCount: results.length,
                      itemBuilder: (context, index) {
                        final item = results[index];
                        final isFavorit = widget.favorit?.contains(item) ?? false;
                        return Card(
                          margin: const EdgeInsets.symmetric(vertical: 6),
                          shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
                          elevation: 4,
                          child: ListTile(
                            leading: ClipRRect(
                              borderRadius: BorderRadius.circular(8),
                              child: Image.asset(item["gambar"]!, width: 50, height: 50, fit: BoxFit.cover),
                            ),
                            title: Text(item["nama"]!, style: const TextStyle(fontWeight: FontWeight.bold)),
                            trailing: IconButton(
                              icon: Icon(isFavorit ? Icons.favorite : Icons.favorite_border, color: Colors.red),
                              onPressed: () {
                                if (widget.onFavoritChanged != null) widget.onFavoritChanged!(item);
                                setState(() {});
                              },
                            ),
                          ),
                        );
                      },
                    ),
            ),
          ],
        ),
      ),
    );
  }
}

// ================= HALAMAN FAVORIT =================
class FavoritPage extends StatelessWidget {
  final List<Map<String, String>> favorit;

  const FavoritPage({super.key, required this.favorit});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Favorit")),
      body: favorit.isEmpty
          ? const Center(child: Text("Belum ada favorit"))
          : Padding(
              padding: const EdgeInsets.all(12),
              child: GridView.builder(
                gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 2,
                  crossAxisSpacing: 10,
                  mainAxisSpacing: 10,
                ),
                itemCount: favorit.length,
                itemBuilder: (context, index) {
                  final item = favorit[index];
                  return Card(
                    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
                    elevation: 4,
                    child: Column(
                      children: [
                        Expanded(
                          child: ClipRRect(
                            borderRadius: const BorderRadius.vertical(top: Radius.circular(12)),
                            child: Image.asset(item["gambar"]!, fit: BoxFit.cover, width: double.infinity),
                          ),
                        ),
                        Padding(
                          padding: const EdgeInsets.all(8),
                          child: Text(item["nama"]!, style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16)),
                        )
                      ],
                    ),
                  );
                },
              ),
            ),
    );
  }
}

// ================= HALAMAN PROFIL =================
class ProfilPage extends StatelessWidget {
  final bool isDarkMode;
  final Function(bool) onThemeChanged;

  const ProfilPage({super.key, required this.isDarkMode, required this.onThemeChanged});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Profil")),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          const SizedBox(height: 20),
          const CircleAvatar(radius: 40, backgroundColor: Colors.teal, child: Icon(Icons.person, size: 50, color: Colors.white)),
          const SizedBox(height: 10),
          const Text("Rian", style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
          const Text("rian@example.com", style: TextStyle(color: Colors.grey)),
          const Divider(height: 30, thickness: 1),
          ListTile(
            leading: const Icon(Icons.dark_mode),
            title: const Text("Mode Gelap"),
            trailing: Switch(value: isDarkMode, onChanged: onThemeChanged),
          ),
          const ListTile(
            leading: Icon(Icons.settings),
            title: Text("Pengaturan Akun"),
          ),
          const ListTile(
            leading: Icon(Icons.logout),
            title: Text("Keluar"),
          ),
        ],
      ),
    );
  }
}
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

// ================= APP UTAMA =================
class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  bool _isDarkMode = false;

  void toggleTheme(bool value) {
    setState(() {
      _isDarkMode = value;
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Kuliner Nusantara',
      debugShowCheckedModeBanner: false,
      theme: _isDarkMode
          ? ThemeData.dark().copyWith(
              appBarTheme: const AppBarTheme(backgroundColor: Colors.green),
            )
          : ThemeData.light().copyWith(
              appBarTheme: const AppBarTheme(backgroundColor: Colors.green),
            ),
      home: MainPage(
        isDarkMode: _isDarkMode,
        onThemeChanged: toggleTheme,
      ),
    );
  }
}

// ================= MAIN PAGE DENGAN NAVBAR =================
class MainPage extends StatefulWidget {
  final bool isDarkMode;
  final Function(bool) onThemeChanged;

  const MainPage({
    super.key,
    required this.isDarkMode,
    required this.onThemeChanged,
  });

  @override
  State<MainPage> createState() => _MainPageState();
}

class _MainPageState extends State<MainPage> {
  int _currentIndex = 0;

  // Daftar favorit
  List<Map<String, String>> favorit = [];

  // Toggle favorit
  void toggleFavorit(Map<String, String> item) {
    setState(() {
      if (favorit.contains(item)) {
        favorit.remove(item);
      } else {
        favorit.add(item);
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    final pages = [
      const HomePage(),
      KulinerPage(onFavoritChanged: toggleFavorit, favorit: favorit),
      SearchPage(onFavoritChanged: toggleFavorit, favorit: favorit),
      FavoritPage(favorit: favorit),
      ProfilPage(isDarkMode: widget.isDarkMode, onThemeChanged: widget.onThemeChanged),
    ];

    return Scaffold(
      body: pages[_currentIndex],
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _currentIndex,
        type: BottomNavigationBarType.fixed,
        onTap: (index) => setState(() => _currentIndex = index),
        items: const [
          BottomNavigationBarItem(icon: Icon(Icons.home), label: "Beranda"),
          BottomNavigationBarItem(icon: Icon(Icons.restaurant), label: "Kuliner"),
          BottomNavigationBarItem(icon: Icon(Icons.search), label: "Cari"),
          BottomNavigationBarItem(icon: Icon(Icons.favorite), label: "Favorit"),
          BottomNavigationBarItem(icon: Icon(Icons.person), label: "Profil"),
        ],
      ),
    );
  }
}

// ================= DATA KULINER =================
const List<Map<String, String>> kulinerList = [
  {"nama": "Rendang", "gambar": "assets/images/rendang.jpg"},
  {"nama": "Sate", "gambar": "assets/images/sate.jpg"},
  {"nama": "Pempek", "gambar": "assets/images/pempek.jpg"},
  {"nama": "Bakso", "gambar": "assets/images/bakso.jpg"},
  {"nama": "Rawon", "gambar": "assets/images/rawon.jpg"},
  {"nama": "Gudeg Jogja", "gambar": "assets/images/gudeg.jpg"},
];

// ================= HALAMAN BERANDA =================
class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Beranda")),
      body: Padding(
        padding: const EdgeInsets.all(12),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const Text(
              "Rekomendasi Kuliner",
              style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 10),
            Expanded(
              child: GridView.builder(
                gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 2,
                  crossAxisSpacing: 10,
                  mainAxisSpacing: 10,
                ),
                itemCount: kulinerList.length,
                itemBuilder: (context, index) {
                  return Card(
                    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
                    elevation: 4,
                    child: Column(
                      children: [
                        Expanded(
                          child: ClipRRect(
                            borderRadius: const BorderRadius.vertical(top: Radius.circular(12)),
                            child: Image.asset(
                              kulinerList[index]["gambar"]!,
                              fit: BoxFit.cover,
                              width: double.infinity,
                            ),
                          ),
                        ),
                        Padding(
                          padding: const EdgeInsets.all(8),
                          child: Text(
                            kulinerList[index]["nama"]!,
                            style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
                          ),
                        )
                      ],
                    ),
                  );
                },
              ),
            )
          ],
        ),
      ),
    );
  }
}

// ================= HALAMAN KULINER =================
class KulinerPage extends StatelessWidget {
  final Function(Map<String, String>) onFavoritChanged;
  final List<Map<String, String>> favorit;

  const KulinerPage({super.key, required this.onFavoritChanged, required this.favorit});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Kuliner Nusantara")),
      body: Padding(
        padding: const EdgeInsets.all(12),
        child: GridView.builder(
          gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
            crossAxisCount: 2,
            crossAxisSpacing: 10,
            mainAxisSpacing: 10,
          ),
          itemCount: kulinerList.length,
          itemBuilder: (context, index) {
            final item = kulinerList[index];
            final isFavorit = favorit.contains(item);

            return GestureDetector(
              onTap: () => onFavoritChanged(item),
              child: Card(
                shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
                elevation: 4,
                child: Column(
                  children: [
                    Expanded(
                      child: Stack(
                        children: [
                          ClipRRect(
                            borderRadius: const BorderRadius.vertical(top: Radius.circular(12)),
                            child: Image.asset(item["gambar"]!, fit: BoxFit.cover, width: double.infinity),
                          ),
                          Positioned(
                            top: 8,
                            right: 8,
                            child: Icon(isFavorit ? Icons.favorite : Icons.favorite_border, color: Colors.red),
                          ),
                        ],
                      ),
                    ),
                    Padding(
                      padding: const EdgeInsets.all(8),
                      child: Text(item["nama"]!, style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16)),
                    )
                  ],
                ),
              ),
            );
          },
        ),
      ),
    );
  }
}

// ================= HALAMAN PENCARIAN =================
class SearchPage extends StatefulWidget {
  final Function(Map<String, String>)? onFavoritChanged;
  final List<Map<String, String>>? favorit;

  const SearchPage({super.key, this.onFavoritChanged, this.favorit});

  @override
  State<SearchPage> createState() => _SearchPageState();
}

class _SearchPageState extends State<SearchPage> {
  String query = "";
  List<Map<String, String>> results = [];

  void search(String value) {
    setState(() {
      query = value;
      results = kulinerList
          .where((item) => item["nama"]!.toLowerCase().contains(query.toLowerCase()))
          .toList();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Cari Kuliner")),
      body: Padding(
        padding: const EdgeInsets.all(12),
        child: Column(
          children: [
            TextField(
              decoration: InputDecoration(
                hintText: "Cari kuliner...",
                prefixIcon: const Icon(Icons.search),
                border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
              ),
              onSubmitted: (value) => search(value), // Tekan Enter
            ),
            const SizedBox(height: 12),
            Expanded(
              child: results.isEmpty
                  ? const Center(child: Text("Hasil pencarian kosong"))
                  : ListView.builder(
                      itemCount: results.length,
                      itemBuilder: (context, index) {
                        final item = results[index];
                        final isFavorit = widget.favorit?.contains(item) ?? false;
                        return Card(
                          margin: const EdgeInsets.symmetric(vertical: 6),
                          shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
                          elevation: 4,
                          child: ListTile(
                            leading: ClipRRect(
                              borderRadius: BorderRadius.circular(8),
                              child: Image.asset(item["gambar"]!, width: 50, height: 50, fit: BoxFit.cover),
                            ),
                            title: Text(item["nama"]!, style: const TextStyle(fontWeight: FontWeight.bold)),
                            trailing: IconButton(
                              icon: Icon(isFavorit ? Icons.favorite : Icons.favorite_border, color: Colors.red),
                              onPressed: () {
                                if (widget.onFavoritChanged != null) widget.onFavoritChanged!(item);
                                setState(() {});
                              },
                            ),
                          ),
                        );
                      },
                    ),
            ),
          ],
        ),
      ),
    );
  }
}

// ================= HALAMAN FAVORIT =================
class FavoritPage extends StatelessWidget {
  final List<Map<String, String>> favorit;

  const FavoritPage({super.key, required this.favorit});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Favorit")),
      body: favorit.isEmpty
          ? const Center(child: Text("Belum ada favorit"))
          : Padding(
              padding: const EdgeInsets.all(12),
              child: GridView.builder(
                gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
                  crossAxisCount: 2,
                  crossAxisSpacing: 10,
                  mainAxisSpacing: 10,
                ),
                itemCount: favorit.length,
                itemBuilder: (context, index) {
                  final item = favorit[index];
                  return Card(
                    shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
                    elevation: 4,
                    child: Column(
                      children: [
                        Expanded(
                          child: ClipRRect(
                            borderRadius: const BorderRadius.vertical(top: Radius.circular(12)),
                            child: Image.asset(item["gambar"]!, fit: BoxFit.cover, width: double.infinity),
                          ),
                        ),
                        Padding(
                          padding: const EdgeInsets.all(8),
                          child: Text(item["nama"]!, style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16)),
                        )
                      ],
                    ),
                  );
                },
              ),
            ),
    );
  }
}

// ================= HALAMAN PROFIL =================
class ProfilPage extends StatelessWidget {
  final bool isDarkMode;
  final Function(bool) onThemeChanged;

  const ProfilPage({super.key, required this.isDarkMode, required this.onThemeChanged});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Profil")),
      body: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          const SizedBox(height: 20),
          const CircleAvatar(radius: 40, backgroundColor: Colors.teal, child: Icon(Icons.person, size: 50, color: Colors.white)),
          const SizedBox(height: 10),
          const Text("Rian", style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
          const Text("rian@example.com", style: TextStyle(color: Colors.grey)),
          const Divider(height: 30, thickness: 1),
          ListTile(
            leading: const Icon(Icons.dark_mode),
            title: const Text("Mode Gelap"),
            trailing: Switch(value: isDarkMode, onChanged: onThemeChanged),
          ),
          const ListTile(
            leading: Icon(Icons.settings),
            title: Text("Pengaturan Akun"),
          ),
          const ListTile(
            leading: Icon(Icons.logout),
            title: Text("Keluar"),
          ),
        ],
      ),
    );
  }
}
Kalo semisal kalian ingin mencobanya ini dia kalian tinggal salin

Gabar :







jika kalian ingin liat lebih lanjut bisa klik link ini :










Oleh : Rian Rama Romansah

Komentar

Postingan populer dari blog ini

Materi Widget

Membuat To Do List Sederhana