「The Complete 2021 Flutter Development Bootcamp with Dart」学習メモ Part 2：Section10-11

みんな大好きFlutterの人気講座「The Complete 2021 Flutter Development Bootcamp with Dart」、前から知ってはいたのですが英語への苦手意識のため放置、どうやらかなり良い講座のようでこのたび通しでやってみることにしました。全部で30時間近くあるらしいので気長に進めていきます。学習の要点メモをまとめていきます。

https://www.udemy.com/course/flutter-bootcamp-with-dart

Section1-9の記事はこちら：
https://qiita.com/igakeso/items/b6e602449cfb2d586f36

・セクション10：List、分岐処理（if/else）、class、instance、object、constructor等
前半の山場、クラスとオブジェクトが登場、オブジェクト志向プログラミングの4要素として、Abstraction、Encapsulation、Inheritance、Polymorphismを紹介、ここをしっかりと理解して次に進むことが大切
自分の知っていたコンストラクタの書き方は省略形だったと初めて知るw
参考リンク
https://dart.dev/guides/language/language-tour#constructors
<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407895/46e87e97-6add-3007-1992-018ba6d8d779.png' width=200/>

```dart
import 'package:flutter/material.dart';
import 'package:rflutter_alert/rflutter_alert.dart';

void main() => runApp(Quizzler());

class Quizzler extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('クイズアプリ'),
          backgroundColor: Colors.grey[900],
        ),
        backgroundColor: Colors.grey[800],
        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> {
  List<Widget> scoreKeeper = [];
  int totalScore = 0 ;
  int quetionNumber = quizBrain._questionBank.length;

  void checkAnswer(bool userSelectedAnswer) {
    bool correctAnswer = quizBrain.getQuestionAnswer();
    if(userSelectedAnswer == correctAnswer) {
      scoreKeeper.add(Icon(Icons.check, color: Colors.green));
      totalScore++;
    } else {
      scoreKeeper.add(Icon(Icons.clear, color: Colors.red));
    }
    quizBrain.nextQuestion();
    if(quizBrain.isFinished() == true) {
      Alert(
        context: context,
        title: "Finished!",
        desc: "全問終了！正解数は$quetionNumber問中$totalScore問でした！",
      ).show();
      quizBrain.reset();
      scoreKeeper = [];
      totalScore = 0;
    }
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.spaceAround,
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        Expanded(
          flex: 5,
          child: Center(
            child: Text(quizBrain.getQuestionText(),
              textAlign: TextAlign.center,
              style: TextStyle(
                fontSize: 25.0,
                color: Colors.white,
              ),
            ),
          ),
        ),
        Expanded(
          child: Row(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              Container(
                width: 150,
                height: 50,
                child: ElevatedButton(
                  child: Text(
                    'True',
                    style: TextStyle(
                      color: Colors.white,
                      fontSize: 20.0,
                    ),
                  ),
                  onPressed: () {
                    checkAnswer(true);
                  },
                  style: ElevatedButton.styleFrom(
                    primary: Colors.green,
                  ),
                ),
              ),
              Container(
                width: 150,
                height: 50,
                child: ElevatedButton(
                  child: Text(
                    'False',
                    style: TextStyle(
                      fontSize: 20.0,
                      color: Colors.white,
                    ),
                  ),
                  onPressed: () {
                    checkAnswer(false);
                  },
                  style: ElevatedButton.styleFrom(
                    primary: Colors.red,
                  ),
                ),
              ),
            ],
          ),
        ),
        Expanded(
          child: Row(
            children: scoreKeeper,
          ),
        ),
      ],
    );
  }
}

class Question{
  String questionText = '';
  bool questionAnswer = true;

  Question(this.questionText, this.questionAnswer);
}

QuizBrain quizBrain = QuizBrain();

class QuizBrain{
  int _questionNumber = 0;

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

  bool getQuestionAnswer(){
    return _questionBank[_questionNumber].questionAnswer;
  }

  void nextQuestion (){
    if(_questionNumber < _questionBank.length){
      _questionNumber++;
    }
  }

  bool isFinished () {
    if(quizBrain._questionNumber == quizBrain._questionBank.length) {
      return true;
    } else {
      return false;
    }
  }

  void reset() {
    _questionNumber = 0;
  }

  List<Question> _questionBank = [
    Question('質問1', true),
    Question('質問2', false),
    Question('質問3', true),
    Question('質問4', true),
    Question('質問5', false),
  ];
}
```

・セクション11：セッション10の復習チャレンジ
条件分岐が力技、新規にVisibility Widgetが登場したくらい
参考リンク：https://api.flutter.dev/flutter/widgets/Visibility-class.html
<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407895/c87d047c-115c-00d1-a81d-7c6b361f5690.png' width =200/>

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

void main() => runApp(Destini());

class Destini extends StatelessWidget {
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData.dark(),
      home: StoryPage(),
    );
  }
}

class StoryPage extends StatefulWidget {
  _StoryPageState createState() => _StoryPageState();
}

class _StoryPageState extends State<StoryPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Story Game'),
        backgroundColor: Colors.blue[900],
      ),
      body: Container(
        decoration: BoxDecoration(
          image: DecorationImage(
            image: AssetImage('images/background.png'),
            fit: BoxFit.cover,
          ),
        ),
        padding: EdgeInsets.symmetric(vertical: 50.0, horizontal: 15.0),
        constraints: BoxConstraints.expand(),
        child: SafeArea(
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            children: [
              Expanded(
                flex: 12,
                child: Center(
                  child: Text(
                    storyBrain.getStory(),
                    style: TextStyle(
                      fontSize: 25.0,
                    ),
                  ),
                ),
              ),
              Expanded(
                flex: 2,
                child: ElevatedButton(
                    onPressed: () {
                      storyBrain.nextStory(1);
                      setState(() {});
                    },
                    child: Text(
                      storyBrain.getChoice1(),
                      style: TextStyle(
                        fontSize: 20.0,
                      ),
                    ),
                    style: ElevatedButton.styleFrom(
                      primary: Colors.orange,
                    )
                ),
              ),
              SizedBox(
                height: 20,
              ),
              Expanded(
                flex: 2,
                child: Visibility(
                  visible: storyBrain.visibleButton2(),
                  child: ElevatedButton(
                    onPressed: () {
                      storyBrain.nextStory(2);
                      setState(() {});
                    },
                    child: Text(
                      storyBrain.getChoice2(),
                      style: TextStyle(
                        fontSize: 20.0,
                      ),
                    ),
                    style: ElevatedButton.styleFrom(
                      primary: Colors.blue,
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

StoryBrain storyBrain = StoryBrain();

class StoryBrain {
  int _storyNumber = 0;

  String getStory() {
    return _storyData[_storyNumber].storyTitle;
  }

  String getChoice1() {
    return _storyData[_storyNumber].choice1;
  }

  String getChoice2() {
    return _storyData[_storyNumber].choice2;
  }

  void nextStory(int choiceNumber) {
    if(_storyNumber == 0 && choiceNumber == 1){
      _storyNumber = 2;
    } else if(_storyNumber == 0 && choiceNumber == 2) {
      _storyNumber = 1;
    } else if(_storyNumber == 2 && choiceNumber == 1) {
      _storyNumber = 5;
    } else if(_storyNumber == 2 && choiceNumber == 2) {
      _storyNumber = 4;
    } else if(_storyNumber == 1 && choiceNumber == 1) {
      _storyNumber = 2;
    } else if(_storyNumber == 1 && choiceNumber == 2) {
      _storyNumber = 3;
    } else if(_storyNumber == 3 || _storyNumber == 4 || _storyNumber == 5) {
      restart();
    }
  }

  void restart() {
    _storyNumber = 0;
  }

  visibleButton2() {
    if(_storyNumber == 3 || _storyNumber == 4 || _storyNumber == 5) {
      return false;
    } else {
      return true;
    }
  }

  List<Story> _storyData = [
    Story('ストーリー0', '選択肢1', '選択肢2'),
    Story('ストーリー1', '選択肢1', '選択肢2'),
    Story('ストーリー2', '選択肢1', '選択肢2'),
    Story('ストーリー3', '最初から始める', ''),
    Story('ストーリー4', '最初から始める', ''),
    Story('ストーリー5', '最初から始める', ''),
  ];
}

class Story {
  String storyTitle;
  String choice1;
  String choice2;

  Story(this.storyTitle, this.choice1, this.choice2);
}
```

また長くなったので記事を分けます。まだ半分以上あるw
https://qiita.com/igakeso/items/f8edac7d1f19c9cbc7f7