Flutter - クイズ問題を出題するアプリ

今回はオブジェクト指向なコードを活かして、クイズ問題を出題するアプリを制作してみました。オブジェクト指向自体になれていないので、かなりハードコーディングな書き方となってしまった（笑）のが反省点なので、次回はこの点を改善したアプリを制作してみようと思います。
![スクリーンショット 2023-02-13 232747.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337578/67caf2af-4d88-c63b-21f3-4ba2e0d410ab.png)
## question.dartのコード
クエスチョンのクラス自体は簡潔な構造で、クエスチョンの内容・対応するブール値の宣言と初期化のみをしています。

```dart
//クエスチョンをクラス化し、オブジェクト指向な書き方にする
class Question{

  String questionText = "";
  bool questionAnswer = true;

  //コンストラクター
  //初期値は空の文字列とtrue
  Question({String q = "", bool a = true}){

    questionText = q;
    questionAnswer = a;

  }

}
```
## main.dartのコード
これまで通りステートフルなウィジェットを埋め込み、クエスチョンオブジェクトのリストを制作しイテレーターを使って順々に出題するという構造にして見ました。オブジェクト指向な書き方に反してかなりハードコーディングな書き方となってしまったので、次回はdartの基礎を見直してより簡潔なコードを書けるようにしようと思います。

```dart
import "package:flutter/material.dart";
import "question.dart";

//メイン
void main() => runApp(Quizzler());

//メインに埋め込むステートレスウィジェット
class Quizzler extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.grey.shade900,
        body: SafeArea(
          child: Padding(
            padding: EdgeInsets.symmetric(horizontal: 10.0),
            child: QuizPage(),
          ),
        ),
      ),
    );
  }
}
//ステートフルウィジェット
class QuizPage extends StatefulWidget {
  @override
  _QuizPageState createState() => _QuizPageState();
}

//クイズアプリの本体
class _QuizPageState extends State<QuizPage> {

  //出題中の問題の番号
  int questionIndex = 0;
  int questionNumber = 0;
  //クエスチョンオブジェクトの一覧
  List<Question> questionBank = [
    Question(q:"これはFlutterを使ったアプリである", a:true),
    Question(q:"このアプリには、Javaというプログラミング言語を使用している", a:false),
    Question(q:"FlutterはGoogleが開発しているフレームワークである", a:true),
    Question(q:"このアプリは嘘つきだ", a:true),
  ];
  //回答があっているかをチェックする
  void checkAnswer(bool userPickedAnswer){
    bool correctAnswer = questionBank[questionNumber].questionAnswer;

    if(questionIndex <= questionBank.length){
      questionIndex++;
    }

    if(userPickedAnswer == correctAnswer){
      print("Right!");
      setState(() {
        //質問番号のインデックスを越えないようにする
        if(questionIndex < questionBank.length){
          questionNumber = questionIndex;
          scoreKeeper.add(
            Icon(Icons.check, color: Colors.green,),
          );
        }
        if(questionIndex == questionBank.length){
          scoreKeeper.add(
            Icon(Icons.check, color: Colors.green,),
          );
        }
      });

    }else{
      print("Wrong!");
      setState(() {
        //質問番号のインデックスを越えないようにする
        if(questionIndex < questionBank.length){
          questionNumber = questionIndex;
          scoreKeeper.add(
            Icon(Icons.close, color: Colors.red,),
          );
        }
        if(questionIndex == questionBank.length){
          scoreKeeper.add(
            Icon(Icons.close, color: Colors.red,),
          );
        }
      });
    }


  }
  //問題欄に何を表示するかをチェックする
  void showQuestion(bool isAnswerDone){

  }

  //ウィジェットを配列として扱い、childに代入したい場合はList<widget>というデータ型にする
  List<Widget> scoreKeeper = [];

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: <Widget>[
        //質問内容のテキスト
        Expanded(
          flex: 5,
          child: Padding(
            padding: EdgeInsets.all(10.0),
            child: Center(
              child: Text(
                //出題中の番号に対応するテキストを表示する
                questionBank[questionNumber].questionText,
                textAlign: TextAlign.center,
                style: TextStyle(
                  fontSize: 25.0,
                  color: Colors.white,
                ),
              ),
            ),
          ),
        ),
        //ボタン - はい
        Expanded(
          child: Padding(
            padding: EdgeInsets.all(15.0),
            child:ElevatedButton(
              child: Text(
                'はい',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 20.0,
                ),
              ),
              onPressed: () {
                checkAnswer(true);
              },
              style: ButtonStyle(
                backgroundColor: MaterialStatePropertyAll<Color>(Colors.green),
              ),
            ),
          ),
        ),
        //ボタン - いいえ
        Expanded(
          child: Padding(
            padding: EdgeInsets.all(15.0),
            child:ElevatedButton(
              child: Text(
                'いいえ',
                style: TextStyle(
                  color: Colors.white,
                  fontSize: 20.0,
                ),
              ),
              onPressed: () {
                checkAnswer(false);
              },
              style: ButtonStyle(
                backgroundColor: MaterialStatePropertyAll<Color>(Colors.red),
              ),
            ),
          ),
        ),
        //TODO: ここにスコアを表示するロウを追加する
        //質問にどう回答したかが記録される
        Row(
          children: scoreKeeper,
        ),
      ],
    );
  }
}
```
dartの基礎に関しては、こちらのコースが良さそうだったので早速勝ってみました。この調子で頑張ろうと思います。
https://www.udemy.com/course/flutter-dart/