Sunday, February 26, 2023

Tutorial Membuat Aplikasi Sejarah Pahlawan Indonesia dengan Flutter

Tutorial Membuat Aplikasi Sejarah Pahlawan Indonesia dengan Flutter
Tutorial Membuat Aplikasi Sejarah Pahlawan Indonesia dengan Flutter
Halo sobat 48 😁. Bagaimana kabarnya? Semoga selalu dalam keadaan sehat ya. Pada kesempatan kali ini saya akan membagikan sebuah artikel yang membahas tentang Tutorial Membuat Aplikasi Sejarah Pahlawan Indonesia dengan Flutter.

Sebelumnya saya sudah pernah membuat tutorial yang sama, namun menggunakan Native ya, bisa kalian lihat tutorialnya DISINI. Untuk di versi Flutter ini, kita harus import library atau assets ke dalam pubspec.yaml ya. Cara import library di Flutter bisa kalian baca DISINI.

Tetapi jika kalian ingin tahu cara mengaplikasikannya, silahkan lanjut baca artikel ini sampai selesai. Jika kamu ingin mencoba tutorial aplikasi ini dengan versi video, berikut saya berikan Videonya:

Jangan lupa subscribe Channel Youtube saya juga ya Azhar Rivaldi, karena disana ada banyak tutorial-tutorial untuk membuat aplikasi lainnya.

Oke langsung saja tanpa basa-basi lagi kita langsung ke langkah-langkahnya ya.

Pertama kalian ubah isi class main.dart menjadi seperti ini:
void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Sejarah Pahlawan Indonesia',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primaryColor: Colors.white,
      ),
      home: const Home(),
    );
  }
}
Berikutnya kalian buat class model model_main.dart :
class ModelMain {
  String? nama;
  String? nama2;
  String? kategori;
  String? asal;
  String? lahir;
  String? usia;
  String? gugur;
  String? lokasimakam;
  String? history;
  String? img;

  ModelMain(this.nama, this.nama2, this.kategori, this.asal, this.lahir,
  this.usia, this.gugur, this.lokasimakam, this.history, this.img);

  ModelMain.fromJson(Map json) {
    nama = json['nama'];
    nama2 = json['nama2'];
    kategori = json['kategori'];
    asal = json['asal'];
    lahir = json['lahir'];
    usia = json['usia'];
    gugur = json['gugur'];
    lokasimakam = json['lokasimakam'];
    history = json['history'];
    img = json['img'];
  }
}
Berikutnya kalian buat class home home_page.dart :
void main() {
  runApp(const Home());
}

class Home extends StatelessWidget {
  const Home({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State createState() {
    return _HomeState();
  }
}

class _HomeState extends State {
  Future> readJsonData() async {
    final jsonData = await root_bundle.rootBundle
        .loadString('assets/pahlawan_nasional.json');
    final listData = json.decode(jsonData) as List;
    return listData.map((e) => ModelMain.fromJson(e)).toList();
  }

  TextEditingController searchController = TextEditingController();
  String? filterData;
  ScrollController scrollController = ScrollController();
  bool showFab = false;

  @override
  initState() {
    searchController.addListener(() {
      setState(() {
        filterData = searchController.text;
      });
    });

    scrollController.addListener(() {
      if (scrollController.offset > 10) {
        showFab = true;
        setState(() {});
      } else {
        showFab = false;
        setState(() {});
      }
    });

    super.initState();
  }

  @override
  void dispose() {
    searchController.dispose();
    scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        title: const Center(
          child: Text('Sejarah Pahlawan',
              style: TextStyle(
                  color: Colors.green,
                  fontWeight: FontWeight.bold,
                  fontSize: 30)),
        ),
        backgroundColor: Colors.white,
        elevation: 0,
      ),
      floatingActionButton: AnimatedOpacity(
        duration: const Duration(milliseconds: 1000),
        opacity: showFab ? 1.0 : 0.0,
        child: FloatingActionButton(
          onPressed: () {
            scrollController.animateTo(0,
                duration: const Duration(milliseconds: 500),
                curve: Curves.fastOutSlowIn);
          },
          backgroundColor: Colors.green,
          child: const Icon(Icons.arrow_upward),
        ),
      ),
      body: Column(
        children: [
          Padding(
            padding: const EdgeInsets.all(8),
            child: TextField(
              controller: searchController,
              decoration: InputDecoration(
                  hintText: 'Cari nama pahlawan',
                  suffixIcon: searchController.text.isEmpty
                      ? null
                      : IconButton(
                          onPressed: searchController.clear,
                          icon: const Icon(
                            Icons.clear,
                            color: Colors.red,
                          ),
                        ),
                  contentPadding: const EdgeInsets.fromLTRB(20, 14, 20, 14),
                  border: OutlineInputBorder(
                      borderRadius: BorderRadius.circular(20)),
                  focusedBorder: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(20),
                    borderSide: const BorderSide(color: Colors.green, width: 2),
                  )),
            ),
          ),
          Expanded(
            child: FutureBuilder(
              future: readJsonData(),
              builder: (context, data) {
                if (data.hasError) {
                  return Center(child: Text("${data.error}"));
                } else if (data.hasData) {
                  var items = data.data as List;
                  return ListView.builder(
                      controller: scrollController,
                      shrinkWrap: true,
                      itemCount: items == null ? 0 : items.length,
                      itemBuilder: (context, index) {
                        return filterData == null || filterData == ""
                            ? GestureDetector(
                                onTap: () {
                                  String nama = items[index].nama.toString();
                                  String nama2 = items[index].nama2.toString();
                                  String kategori = items[index].kategori.toString();
                                  String asal = items[index].asal.toString();
                                  String usia = items[index].usia.toString();
                                  String lahir = items[index].lahir.toString();
                                  String gugur = items[index].gugur.toString();
                                  String lokasimakam = items[index].lokasimakam.toString();
                                  String history = items[index].history.toString();
                                  String img = items[index].img.toString();
                                  Navigator.push(
                                      context,
                                      MaterialPageRoute(
                                          builder: (context) => DetailPahlawan(
                                              nama: nama,
                                              nama2: nama2,
                                              kategori: kategori,
                                              asal: asal,
                                              usia: usia,
                                              lahir: lahir,
                                              gugur: gugur,
                                              lokasimakam: lokasimakam,
                                              history: history,
                                              img: img)));
                                },
                                child: Card(
                                  shape: RoundedRectangleBorder(
                                      borderRadius: BorderRadius.circular(10)),
                                  elevation: 5,
                                  margin: const EdgeInsets.all(10),
                                  color: Colors.white,
                                  child: Padding(
                                    padding: const EdgeInsets.all(8),
                                    child: Row(
                                      children: [
                                        Container(
                                          margin:
                                              const EdgeInsets.only(right: 14),
                                          width: 70,
                                          height: 70,
                                          decoration: BoxDecoration(
                                            shape: BoxShape.circle,
                                            image: DecorationImage(
                                              fit: BoxFit.cover,
                                              image: NetworkImage(
                                                items[index].img.toString(),
                                              ),
                                            ),
                                          ),
                                        ),
                                        Flexible(
                                          child: Column(
                                            crossAxisAlignment:
                                                CrossAxisAlignment.start,
                                            mainAxisAlignment:
                                                MainAxisAlignment.center,
                                            children: [
                                              Text(
                                                items[index].nama.toString(),
                                                style: const TextStyle(
                                                    color: Colors.black,
                                                    fontSize: 18),
                                                maxLines: 2,
                                              ),
                                              const SizedBox(height: 10),
                                              Text(
                                                items[index].nama2.toString(),
                                                style: const TextStyle(
                                                    color: Colors.black,
                                                    fontSize: 14),
                                                maxLines: 2,
                                              ),
                                            ],
                                          ),
                                        )
                                      ],
                                    ),
                                  ),
                                ),
                              )
                            : '${items[index].nama}'
                                    .toLowerCase()
                                    .contains(filterData!.toLowerCase())
                                ? GestureDetector(
                                    onTap: () {},
                                    child: Card(
                                      shape: RoundedRectangleBorder(
                                          borderRadius:
                                              BorderRadius.circular(10)),
                                      elevation: 4,
                                      margin: const EdgeInsets.all(10),
                                      color: Colors.white,
                                      child: Padding(
                                        padding: const EdgeInsets.all(8),
                                        child: Row(
                                          children: [
                                            Container(
                                              margin: const EdgeInsets.only(
                                                  right: 14),
                                              width: 70,
                                              height: 70,
                                              decoration: BoxDecoration(
                                                shape: BoxShape.circle,
                                                image: DecorationImage(
                                                  fit: BoxFit.cover,
                                                  image: NetworkImage(
                                                    items[index].img.toString(),
                                                  ),
                                                ),
                                              ),
                                            ),
                                            Flexible(
                                              child: Column(
                                                crossAxisAlignment:
                                                    CrossAxisAlignment.start,
                                                mainAxisAlignment:
                                                    MainAxisAlignment.center,
                                                children: [
                                                  Text(
                                                    items[index]
                                                        .nama
                                                        .toString(),
                                                    style: const TextStyle(
                                                        color: Colors.black,
                                                        fontSize: 18),
                                                    maxLines: 2,
                                                  ),
                                                  const SizedBox(height: 10),
                                                  Container(
                                                    padding:
                                                        const EdgeInsets.all(4),
                                                    decoration: BoxDecoration(
                                                        borderRadius:
                                                            BorderRadius
                                                                .circular(10),
                                                        color: Colors.green),
                                                    child: Text(
                                                      items[index]
                                                          .kategori
                                                          .toString(),
                                                      style: const TextStyle(
                                                          color: Colors.white,
                                                          fontSize: 10),
                                                      maxLines: 2,
                                                    ),
                                                  ),
                                                ],
                                              ),
                                            )
                                          ],
                                        ),
                                      ),
                                    ),
                                  )
                                : Container();
                      });
                } else {
                  return const Center(
                    child: CircularProgressIndicator(),
                  );
                }
              },
            ),
          ),
        ],
      ),
    );
  }
}
Langkah terakhir kalian buat class dengan nama detail_page.dart. Untuk isinya seperti ini:
class DetailPahlawan extends StatefulWidget {

  final String nama, nama2, kategori, asal, usia, lahir, gugur, lokasimakam, history, img;

  const DetailPahlawan(
      {Key? key, required this.nama, required this.nama2, required this.kategori,
        required this.asal, required this.usia, required this.lahir,
        required this.gugur, required this.lokasimakam, required this.history, required this.img})
      : super(key: key);

  @override
  _DetailPahlawanState createState() => _DetailPahlawanState(nama, nama2,
      kategori, asal, usia, lahir, gugur,
      lokasimakam, history, img);
}

class _DetailPahlawanState extends State {

  String nama, nama2, kategori, asal, usia, lahir, gugur, lokasimakam, history, img;
  _DetailPahlawanState(this.nama, this.nama2, this.kategori, this.asal,
      this.usia, this.lahir, this.gugur, this.lokasimakam, this.history, this.img);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Stack(
        children: [
          Container(
            width: MediaQuery.of(context).size.width,
            height: 296,
            decoration: BoxDecoration(
              image: DecorationImage(
                  image: NetworkImage(img), fit: BoxFit.cover),
            ),
          ),
          Align(
            alignment: Alignment.topLeft,
            child: InkWell(
              onTap: () => Navigator.pop(context),
              child: SafeArea(
                child: Container(
                  width: 50,
                  height: 50,
                  margin: const EdgeInsets.only(left: 20, top: 10),
                  decoration: const BoxDecoration(
                    color: Colors.white,
                    shape: BoxShape.circle,
                  ),
                  child: const Padding(
                    padding: EdgeInsets.only(left: 8),
                    child: Icon(Icons.arrow_back_ios),
                  ),
                ),
              ),
            ),
          ),
          Container(
            width: MediaQuery.of(context).size.width,
            margin: const EdgeInsets.only(top: 250),
            padding: const EdgeInsets.symmetric(horizontal: 20),
            decoration: const BoxDecoration(
              color: Colors.white,
              borderRadius: BorderRadius.only(
                topLeft: Radius.circular(28),
                topRight: Radius.circular(28),
              ),
            ),
            child: SingleChildScrollView(
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  const SizedBox(
                    height: 20,
                  ),
                  const Text(
                    "Biodata Pahlawan :",
                    style: TextStyle(color: Colors.black, fontSize: 20, fontWeight: FontWeight.bold),
                  ),
                  const SizedBox(
                    height: 20,
                  ),
                  Text(
                    "Nama : $nama",
                    style: const TextStyle(fontSize: 14, color: Colors.black),
                  ),
                  const SizedBox(
                    height: 8,
                  ),
                  Text(
                    "Nama Lengkap : $nama2",
                    style: const TextStyle(fontSize: 14, color: Colors.black),
                  ),
                  const SizedBox(
                    height: 8,
                  ),
                  Text(
                    "Lahir : $lahir",
                    style: const TextStyle(fontSize: 14, color: Colors.black),
                  ),
                  const SizedBox(
                    height: 8,
                  ),
                  Text(
                    "Wafat : $gugur",
                    style: const TextStyle(fontSize: 14, color: Colors.black),
                  ),
                  const SizedBox(
                    height: 8,
                  ),
                  Text(
                    "Lokasi Makam : $lokasimakam",
                    style: const TextStyle(fontSize: 14, color: Colors.black),
                  ),
                  const SizedBox(
                    height: 8,
                  ),
                  Text(
                    "Riwayat : $history",
                    style: const TextStyle(fontSize: 14, color: Colors.black),
                  ),
                  const SizedBox(
                    height: 8,
                  ),
                ],
              ),
            ),
          )
        ],
      ),
    );
  }
}
Jika kalian mengikuti langkah-langkah diatas dengan baik, pasti aplikasi yang kalian buat akan berjalan sebagaimana mestinya. Untuk Link Source Code bisa kalian unduh DISINI. Namun jika mengalami Error, silahkan berikan komentar dan kita diskusikan bersama atau bisa ditonton sampai habis video tutorialnya.

Support Blog Rivaldi 48 agar terus bisa membagikan artikel-artikel yang bermanfaat dengan cara klik link Sociabuzz dibawah ini :
https://sociabuzz.com/azharrvldi_/donate (bisa pakai GoPay, OVO, DANA, Bank Transfer)

Demikian informasi yang saya bagikan untuk kalian. Jangan lupa bagikan artikel ini ke teman-teman kalian agar ikut membaca Tutorial Membuat Aplikasi Sejarah Pahlawan Indonesia dengan Flutter ini. Subscribe juga blog Rivaldi 48 ini agar kalian mendapatkan notifikasi saat Admin update artikel terbaru. Semoga kalian lebih nyaman dan mudah dalam mengakses Blog Rivaldi 48 dimanapun kalian berada. Terima Kasih. Follow Instagram Admin @azhardvls_

0 Comments

Post a Comment

Silahkan tinggalkan komentar jika Anda punya saran, kritik, atau pertanyaan seputar topik pembahasan. Gunakan bahasa yang bijak dan santun. Terima Kasih.