Skip to content

Quiz App

Pada materi ini kita akan membuat aplikasi kuis seperti berikut ini.

Quiz App

Aplikasi ini akan berbentuk kuis dengan jawaban benar atau salah. Terdapat sebuah pernyataan dan tombol True dan False. Saat tombol True atau False ditekan, aplikasi akan menampilkan icon benar atau salah dibagian bawah dan akan berpindah ke pernyataan berikutnya. Saat seluruh soal telah selesai, aplikasi akan menampilkan pesan bahwa kuis sudah selesai, dan akan mengulang kuis dari awal kembali.

New Project

Buat sebuah project baru dan sesuaikan kode main.dart seperti berikut ini.

main.dart
import 'package:flutter/material.dart';
import 'package:quiz/pages/quiz_page.dart';

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

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.grey.shade900,
        body: const SafeArea(
          child: Padding(
            padding: EdgeInsets.symmetric(horizontal: 10.0),
            child: QuizPage(),
          ),
        ),
      ),
    );
  }
}

Kemudian buat folder pages dan buat file quiz_page.dart. Karena aplikasi akan memiliki konten yang dinamis, maka kita menggunakan Stateful Widget untuk class QuizPage.

quiz_page.dart
import 'package:flutter/material.dart';

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

  @override
  State<QuizPage> createState() => _QuizPageState();
}

class _QuizPageState extends State<QuizPage> {
  @override
  Widget build(BuildContext context) {
    return Column();
  }
}

rflutter_alert Package

Saat semua soal telah dijawab, aplikasi akan menampilkan pesan bahwa kuis telah selesai. Untuk membuat dialog pesan tersebut, kita akan menggunakan package rflutter_alert dari https://pub.dev/packages/rflutter_alert. Tambahkan rflutter_alert: ^2.0.7 pada dependencies di file pubspec.yaml, atau ketikkan flutter pub add rflutter_alert di terminal. Kemudian import package tersbut di file quiz_page.dart.

import 'package:rflutter_alert/rflutter_alert.dart';

Layout

Layout aplikasi ini terdiri dari 1 column dengan 4 children yaitu Text, dua Elevated Button, dan Row.

Layout

Berikut ini adalah kode layout

quiz_page.dart
class _QuizPageState extends State<QuizPage> {
  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        const Expanded(
          flex: 5,
          child: Padding(
            padding: EdgeInsets.all(15.0),
            child: Center(
              child: Text(
                'Tempat soal',
                style: TextStyle(color: Colors.white, fontSize: 25),
                textAlign: TextAlign.center,
              ),
            ),
          ),
        ),
        Expanded(
          child: Padding(
            padding: const EdgeInsets.all(15.0),
            child: TextButton(
              style: TextButton.styleFrom(
                  foregroundColor: Colors.white,
                  backgroundColor: Colors.green,
                  // fixedSize: Size.fromHeight(60),
                  textStyle: const TextStyle(
                    fontSize: 20,
                  )),
              child: const Text('True'),
              onPressed: () {},
            ),
          ),
        ),
        Expanded(
          child: Padding(
            padding: const EdgeInsets.all(15.0),
            child: TextButton(
              style: TextButton.styleFrom(
                  foregroundColor: Colors.white,
                  backgroundColor: Colors.red,
                  // fixedSize: Size.fromHeight(60),
                  textStyle: const TextStyle(
                    fontSize: 20,
                  )),
              child: const Text('False'),
              onPressed: () {},
            ),
          ),
        ),
        const SizedBox(
          height: 30.0,
          child: Row(),
        )
      ],
    );
  }
}

Question Class

Pada aplikasi ini kita akan menggunakan konsep object oriented. Untuk merepresentasikan soal-soal, kita akan membuat class Question dengan property soal dan jawabannya. Buat file baru di folder lib dengan nama question.dart, lalu buat kode class Question seperti berikut ini.

question.dart
class Question {
  String questionText;
  bool questionAnswer;

  // Question({required this.questionText, required this.questionAnswer});
  Question(this.questionText, this.questionAnswer);
}

QuizController Class

Berikutnya kita akan membuat class QuizController yang berfungsi untuk mengolah soal-soal, navigasi soal, memeriksa jawaban, dan mengulang kuis. Buat file baru dan beri nama quiz_controller.dart dan buat kode class QuestionController seperti berikut ini.

quiz_controller.dart
import 'question.dart';

class QuizController {
  int _questionNumber = 0;

  final List<Question> questionBank = [
    Question('Computer Processing Unit adalah kepanjangan dari CPU.', false),
    Question(
        'LAN adalah jaringan komputer dengan area yang berskala kecil.', true),
    Question('Biner adalah sistem bilangan basis 2', true),
    Question('Alamat memori menggunakan basis bilangan hexadesimal.', true),
    Question('Read Acces Memory adalah kepanjangan dari RAM.', false),
    Question('Oktal adalah bilangan basis 16', false),
    Question('Kepanjangan BIOS adalah Basic Input Output System.', true),
    Question(
        'ALU adalah komponen dari CPU yang bertugas melakukan perhitungan aritmatika dan pembadingan.',
        true),
    Question('Open System Interconnection adalah kepanjangan dari OSI.', true),
    Question('File Technology Protocol adalah kepanjangan dari FTP.', false),
  ];

  void nextQuestion() {
    if (_questionNumber < questionBank.length - 1) {
      _questionNumber++;
    }
  }

  String getQuestionText() {
    return questionBank[_questionNumber].questionText;
  }

  bool getCorrectAnswer() {
    return questionBank[_questionNumber].questionAnswer;
  }

  bool isFinished() {
    if (_questionNumber >= questionBank.length - 1) {
      return true;
    } else {
      return false;
    }
  }

  void reset() {
    _questionNumber = 0;
  }
}

Score Keeper

Di file quiz_page.dart, kita membuat sebuah list dengan nama scoreKeeper untuk menyimpan icon dan yang akan ditampilkan dibagian bawah saat user menjawab dengan benar atau salah.

List<Icon> scoreKeeper = [];

quizController Object

Berikutnya kita membuat objek quizController dari class QuizController yang telah dibuat sebelumnya.

QuizController quizController = QuizController();

Jangan lupa untuk mengimpor file quiz_controller.dart di file quiz_page.dart

import 'package:quiz/quiz_controller.dart';

checkAnswer Method

Fungsi checkAnswer merupakan logika utama dari aplikasi ini. Fungsi ini berfungsi untuk memeriksa jawaban user dan menampilkan icon yang sesuai, menampilkan soal berikutnya, memeriksa apakah sudah mencapai soal terakhir, menampilkan dialog kuis berakhir, dan melakukan reset kuis.

void checkAnswer(bool userAnswer) {
  bool correctAnswer = quizController.getCorrectAnswer();

  setState(() {
    if (userAnswer == correctAnswer) {
      scoreKeeper.add(const Icon(
        Icons.check,
        color: Colors.green,
      ));
    } else {
      scoreKeeper.add(const Icon(
        Icons.close,
        color: Colors.red,
      ));
    }

    if (quizController.isFinished()) {
      Alert(
        context: context,
        title: 'Finished!',
        desc: 'You\'ve reached the end of the quiz.',
        buttons: [
          DialogButton(
            onPressed: () => Navigator.pop(context),
            child: const Text(
              "OK",
            ),
          )
        ],
      ).show();

      quizController.reset();
      scoreKeeper = [];
    } else {
      quizController.nextQuestion();
    }
  });
}

Call the Method

Langkah terakhir adalah memanggil method yang telah kita buat pada widget Text dan ElevatedButton serta menambahkan variabel scoreKeeper pada Row di bagian bawah.

Pada widget Text, ubah teks 'Tempat soal' menjadi quizController.getQuestionText().

Text(
  quizController.getQuestionText(),
  style: const TextStyle(color: Colors.white, fontSize: 25),
  textAlign: TextAlign.center,
)

Pada fungsi onPressed() di tombol True, tambahkan kode untuk menjalankan fungsi checkAnswer dengan parameter true, dan dengan parameter false pada fungsi onPressed() tombol False.

Tombol True

checkAnswer(true);

Tombol False

checkAnswer(false);

Pada Row yang merupakan anak terakhir dari Column, tambahkan variabel scoreKeeper untuk dapat menampilkan icon dan .

Row(
  children: scoreKeeper,
)

Full Code Quiz Page

quiz_page.dart
import 'package:flutter/material.dart';
import 'package:quiz/quiz_controller.dart';
import 'package:rflutter_alert/rflutter_alert.dart';

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

  @override
  State<QuizPage> createState() => _QuizPageState();
}

class _QuizPageState extends State<QuizPage> {
  List<Icon> scoreKeeper = [];
  QuizController quizController = QuizController();

  void checkAnswer(bool userAnswer) {
    bool correctAnswer = quizController.getCorrectAnswer();

    setState(() {
      if (userAnswer == correctAnswer) {
        scoreKeeper.add(const Icon(
          Icons.check,
          color: Colors.green,
        ));
      } else {
        scoreKeeper.add(const Icon(
          Icons.close,
          color: Colors.red,
        ));
      }

      if (quizController.isFinished()) {
        Alert(
          context: context,
          title: 'Finished!',
          desc: 'You\'ve reached the end of the quiz.',
          buttons: [
            DialogButton(
              onPressed: () => Navigator.pop(context),
              child: const Text(
                "OK",
              ),
            )
          ],
        ).show();

        quizController.reset();
        scoreKeeper = [];
      } else {
        quizController.nextQuestion();
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        Expanded(
          flex: 5,
          child: Padding(
            padding: const EdgeInsets.all(10.0),
            child: Center(
              child: Text(
                quizController.getQuestionText(),
                style: const TextStyle(color: Colors.white, fontSize: 25),
                textAlign: TextAlign.center,
              ),
            ),
          ),
        ),
        Expanded(
          child: Padding(
            padding: const EdgeInsets.all(15.0),
            child: TextButton(
              style: TextButton.styleFrom(
                  foregroundColor: Colors.white,
                  backgroundColor: Colors.green,
                  // fixedSize: Size.fromHeight(60),
                  textStyle: const TextStyle(
                    fontSize: 20,
                  )),
              child: const Text('True'),
              onPressed: () {
                checkAnswer(true);
              },
            ),
          ),
        ),
        Expanded(
          child: Padding(
            padding: const EdgeInsets.all(15.0),
            child: TextButton(
              style: TextButton.styleFrom(
                  foregroundColor: Colors.white,
                  backgroundColor: Colors.red,
                  // fixedSize: Size.fromHeight(60),
                  textStyle: const TextStyle(
                    fontSize: 20,
                  )),
              child: const Text('False'),
              onPressed: () {
                checkAnswer(false);
              },
            ),
          ),
        ),
        SizedBox(
          height: 30.0,
          child: Row(
            children: scoreKeeper,
          ),
        )
      ],
    );
  }
}

Challenge

Ubah kode menjadi seperti berikut ini

Quiz App

Quiz

Setelah berhasil membuat aplikasi quiz dan mempelajari kodenya, silahkan kerjakan kuis berikut ini https://forms.gle/ayYuKXgMTMNAD9NG9.