From 3084187ff1cc556f4858145edfcee20c1f3299db Mon Sep 17 00:00:00 2001 From: Herwig Birke Date: Thu, 8 Feb 2024 08:30:10 +0100 Subject: [PATCH] Start Abschnitt 4: Debugging Flutter Apps --- lib/answer_button.dart | 7 +- lib/data/questions.dart | 2 +- lib/main.dart | 3 +- lib/models/quiz_question.dart | 8 +- lib/questions_screen.dart | 9 +- lib/questions_summary.dart | 83 ------------------- .../question_identifier.dart | 35 ++++++++ lib/questions_summary/questions_summary.dart | 25 ++++++ lib/questions_summary/summary_item.dart | 58 +++++++++++++ lib/quiz.dart | 41 +++++---- lib/results_screen.dart | 29 ++++--- lib/start_screen.dart | 13 ++- 12 files changed, 182 insertions(+), 131 deletions(-) delete mode 100644 lib/questions_summary.dart create mode 100644 lib/questions_summary/question_identifier.dart create mode 100644 lib/questions_summary/questions_summary.dart create mode 100644 lib/questions_summary/summary_item.dart diff --git a/lib/answer_button.dart b/lib/answer_button.dart index b94f932..b69dfe4 100644 --- a/lib/answer_button.dart +++ b/lib/answer_button.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; class AnswerButton extends StatelessWidget { - AnswerButton({ + const AnswerButton({ super.key, required this.answerText, required this.onTap, @@ -15,7 +15,10 @@ class AnswerButton extends StatelessWidget { return ElevatedButton( onPressed: onTap, style: ElevatedButton.styleFrom( - padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 40), + padding: const EdgeInsets.symmetric( + vertical: 10, + horizontal: 40, + ), backgroundColor: const Color.fromARGB(255, 33, 1, 95), foregroundColor: Colors.white, shape: RoundedRectangleBorder( diff --git a/lib/data/questions.dart b/lib/data/questions.dart index 1f0b932..29afb03 100644 --- a/lib/data/questions.dart +++ b/lib/data/questions.dart @@ -52,4 +52,4 @@ const questions = [ 'By calling updateState()', ], ), -]; \ No newline at end of file +]; diff --git a/lib/main.dart b/lib/main.dart index 70d8038..67d72e2 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,7 @@ -import 'package:adv_basics/quiz.dart'; import 'package:flutter/material.dart'; +import 'package:adv_basics/quiz.dart'; + void main() { runApp(const Quiz()); } diff --git a/lib/models/quiz_question.dart b/lib/models/quiz_question.dart index 7e9aee3..5ef8162 100644 --- a/lib/models/quiz_question.dart +++ b/lib/models/quiz_question.dart @@ -4,9 +4,9 @@ class QuizQuestion { final String text; final List answers; - List get shuffeldAnswers { - final shuffeldList = List.of(answers); - shuffeldList.shuffle(); - return shuffeldList; + List get shuffledAnswers { + final shuffledList = List.of(answers); + shuffledList.shuffle(); + return shuffledList; } } diff --git a/lib/questions_screen.dart b/lib/questions_screen.dart index 327ee2c..6fd78d0 100644 --- a/lib/questions_screen.dart +++ b/lib/questions_screen.dart @@ -1,7 +1,8 @@ import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; + import 'package:adv_basics/answer_button.dart'; import 'package:adv_basics/data/questions.dart'; -import 'package:google_fonts/google_fonts.dart'; class QuestionsScreen extends StatefulWidget { const QuestionsScreen({ @@ -22,8 +23,10 @@ class _QuestionsScreenState extends State { void answerQuestion(String selectedAnswer) { widget.onSelectAnswer(selectedAnswer); + // currentQuestionIndex = currentQuestionIndex + 1; + // currentQuestionIndex += 1; setState(() { - currentQuestionIndex++; + currentQuestionIndex++; // increments the value by 1 }); } @@ -49,7 +52,7 @@ class _QuestionsScreenState extends State { textAlign: TextAlign.center, ), const SizedBox(height: 30), - ...currentQuestion.shuffeldAnswers.map((answer) { + ...currentQuestion.shuffledAnswers.map((answer) { return AnswerButton( answerText: answer, onTap: () { diff --git a/lib/questions_summary.dart b/lib/questions_summary.dart deleted file mode 100644 index a25b1b6..0000000 --- a/lib/questions_summary.dart +++ /dev/null @@ -1,83 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:google_fonts/google_fonts.dart'; - -class QuestionsSummary extends StatelessWidget { - const QuestionsSummary(this.summaryData, {super.key}); - - final List> summaryData; - - @override - Widget build(BuildContext context) { - return SizedBox( - height: 300, - child: SingleChildScrollView( - child: Column( - children: summaryData.map( - (data) { - return Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - CircleAvatar( - radius: 15, - backgroundColor: - (data['correct_answer'] == data['user_answer']) - ? Colors.green - : Colors.red, - child: Center( - child: Text( - ((data['question_index'] as int) + 1).toString(), - style: const TextStyle( - color: Colors.white, - ), - ), - ), - ), - SizedBox( - width: 20, - ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - data['question'] as String, - style: GoogleFonts.lato( - color: Colors.white, - fontSize: 14, - ), - textAlign: TextAlign.left, - ), - const SizedBox( - height: 5, - ), - Text( - data['user_answer'] as String, - style: GoogleFonts.lato( - color: Color.fromARGB(255, 201, 153, 251), - fontSize: 14, - ), - textAlign: TextAlign.left, - ), - Text( - data['correct_answer'] as String, - style: GoogleFonts.lato( - color: - (data['correct_answer'] == data['user_answer']) - ? Colors.green - : Colors.red, - fontSize: 14, - ), - textAlign: TextAlign.left, - ), - ], - ), - ), - ], - ); - }, - ).toList(), - ), - ), - ); - } -} diff --git a/lib/questions_summary/question_identifier.dart b/lib/questions_summary/question_identifier.dart new file mode 100644 index 0000000..925339f --- /dev/null +++ b/lib/questions_summary/question_identifier.dart @@ -0,0 +1,35 @@ +import 'package:flutter/material.dart'; + +class QuestionIdentifier extends StatelessWidget { + const QuestionIdentifier({ + super.key, + required this.isCorrectAnswer, + required this.questionIndex, + }); + + final int questionIndex; + final bool isCorrectAnswer; + + @override + Widget build(BuildContext context) { + final questionNumber = questionIndex + 1; + return Container( + width: 30, + height: 30, + alignment: Alignment.center, + decoration: BoxDecoration( + color: isCorrectAnswer + ? const Color.fromARGB(255, 150, 198, 241) + : const Color.fromARGB(255, 249, 133, 241), + borderRadius: BorderRadius.circular(100), + ), + child: Text( + questionNumber.toString(), + style: const TextStyle( + fontWeight: FontWeight.bold, + color: Color.fromARGB(255, 22, 2, 56), + ), + ), + ); + } +} diff --git a/lib/questions_summary/questions_summary.dart b/lib/questions_summary/questions_summary.dart new file mode 100644 index 0000000..9ce8451 --- /dev/null +++ b/lib/questions_summary/questions_summary.dart @@ -0,0 +1,25 @@ +import 'package:flutter/material.dart'; + +import 'package:adv_basics/questions_summary/summary_item.dart'; + +class QuestionsSummary extends StatelessWidget { + const QuestionsSummary(this.summaryData, {super.key}); + + final List> summaryData; + + @override + Widget build(BuildContext context) { + return SizedBox( + height: 400, + child: SingleChildScrollView( + child: Column( + children: summaryData.map( + (data) { + return SummaryItem(data); + }, + ).toList(), + ), + ), + ); + } +} diff --git a/lib/questions_summary/summary_item.dart b/lib/questions_summary/summary_item.dart new file mode 100644 index 0000000..3fac500 --- /dev/null +++ b/lib/questions_summary/summary_item.dart @@ -0,0 +1,58 @@ +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; + +import 'package:adv_basics/questions_summary/question_identifier.dart'; + +class SummaryItem extends StatelessWidget { + const SummaryItem(this.itemData, {super.key}); + + final Map itemData; + + @override + Widget build(BuildContext context) { + final isCorrectAnswer = + itemData['user_answer'] == itemData['correct_answer']; + + return Padding( + padding: const EdgeInsets.symmetric( + vertical: 8, + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + QuestionIdentifier( + isCorrectAnswer: isCorrectAnswer, + questionIndex: itemData['question'] as int, + ), + const SizedBox(width: 20), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + itemData['question'] as String, + style: GoogleFonts.lato( + color: Colors.white, + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + const SizedBox( + height: 5, + ), + Text(itemData['user_answer'] as String, + style: const TextStyle( + color: Color.fromARGB(255, 202, 171, 252), + )), + Text(itemData['correct_answer'] as String, + style: const TextStyle( + color: Color.fromARGB(255, 181, 254, 246), + )), + ], + ), + ), + ], + ), + ); + } +} diff --git a/lib/quiz.dart b/lib/quiz.dart index 826306a..63ee681 100644 --- a/lib/quiz.dart +++ b/lib/quiz.dart @@ -1,8 +1,9 @@ -import 'package:adv_basics/questions_screen.dart'; +import 'package:flutter/material.dart'; + import 'package:adv_basics/start_screen.dart'; +import 'package:adv_basics/questions_screen.dart'; import 'package:adv_basics/data/questions.dart'; import 'package:adv_basics/results_screen.dart'; -import 'package:flutter/material.dart'; class Quiz extends StatefulWidget { const Quiz({super.key}); @@ -14,41 +15,45 @@ class Quiz extends StatefulWidget { } class _QuizState extends State { - List selectedAnswers = []; - var activeScreen = 'start-screen'; - - void switchScreen() { - selectedAnswers.clear(); + List _selectedAnswers = []; + var _activeScreen = 'start-screen'; + void _switchScreen() { setState(() { - activeScreen = 'questions-screen'; + _activeScreen = 'questions-screen'; }); } - void chooseAnswer(String answer) { - selectedAnswers.add(answer); + void _chooseAnswer(String answer) { + _selectedAnswers.add(answer); - if (selectedAnswers.length == questions.length) { + if (_selectedAnswers.length == questions.length) { setState(() { - activeScreen = 'results-screen'; + _activeScreen = 'results-screen'; }); } } + void restartQuiz() { + setState(() { + _activeScreen = 'questions-screen'; + }); + } + @override Widget build(context) { - Widget screenWidget = StartScreen(switchScreen); + Widget screenWidget = StartScreen(_switchScreen); - if (activeScreen == 'questions-screen') { + if (_activeScreen == 'questions-screen') { screenWidget = QuestionsScreen( - onSelectAnswer: chooseAnswer, + onSelectAnswer: _chooseAnswer, ); } - if (activeScreen == 'results-screen') { + if (_activeScreen == 'results-screen') { screenWidget = ResultsScreen( - chosenAnswers: selectedAnswers, - onRestartQuiz: switchScreen, + chosenAnswers: _selectedAnswers, + onRestart: restartQuiz, ); } diff --git a/lib/results_screen.dart b/lib/results_screen.dart index 0b9f1d3..30aa6f2 100644 --- a/lib/results_screen.dart +++ b/lib/results_screen.dart @@ -1,17 +1,18 @@ import 'package:flutter/material.dart'; -import 'package:adv_basics/questions_summary.dart'; + import 'package:adv_basics/data/questions.dart'; +import 'package:adv_basics/questions_summary/questions_summary.dart'; import 'package:google_fonts/google_fonts.dart'; class ResultsScreen extends StatelessWidget { const ResultsScreen({ super.key, required this.chosenAnswers, - required this.onRestartQuiz, + required this.onRestart, }); + final void Function() onRestart; final List chosenAnswers; - final void Function() onRestartQuiz; List> get summaryData { final List> summary = []; @@ -22,7 +23,7 @@ class ResultsScreen extends StatelessWidget { 'question_index': i, 'question': questions[i].text, 'correct_answer': questions[i].answers[0], - 'user_answer': chosenAnswers[i], + 'user_answer': chosenAnswers[i] }, ); } @@ -32,7 +33,7 @@ class ResultsScreen extends StatelessWidget { @override Widget build(BuildContext context) { - final numTotalQuestions = summaryData.length; + final numTotalQuestions = questions.length; final numCorrectQuestions = summaryData .where( (data) => data['user_answer'] == data['correct_answer'], @@ -49,8 +50,8 @@ class ResultsScreen extends StatelessWidget { Text( 'You answered $numCorrectQuestions out of $numTotalQuestions questions correctly!', style: GoogleFonts.lato( - color: const Color.fromARGB(255, 201, 153, 251), - fontSize: 24, + color: const Color.fromARGB(255, 230, 200, 253), + fontSize: 20, fontWeight: FontWeight.bold, ), textAlign: TextAlign.center, @@ -58,19 +59,17 @@ class ResultsScreen extends StatelessWidget { const SizedBox( height: 30, ), - QuestionsSummary( - summaryData, - ), + QuestionsSummary(summaryData), const SizedBox( height: 30, ), - OutlinedButton.icon( - onPressed: onRestartQuiz, - style: OutlinedButton.styleFrom( + TextButton.icon( + onPressed: onRestart, + style: TextButton.styleFrom( foregroundColor: Colors.white, ), - icon: const Icon(Icons.update), - label: const Text('Restart Quiz'), + icon: const Icon(Icons.refresh), + label: const Text('Restart Quiz!'), ) ], ), diff --git a/lib/start_screen.dart b/lib/start_screen.dart index 215ef00..4a24500 100644 --- a/lib/start_screen.dart +++ b/lib/start_screen.dart @@ -17,9 +17,14 @@ class StartScreen extends StatelessWidget { width: 300, color: const Color.fromARGB(150, 255, 255, 255), ), - const SizedBox( - height: 80, - ), + // Opacity( + // opacity: 0.6, + // child: Image.asset( + // 'assets/images/quiz-logo.png', + // width: 300, + // ), + // ), + const SizedBox(height: 80), Text( 'Learn Flutter the fun way!', style: GoogleFonts.lato( @@ -35,7 +40,7 @@ class StartScreen extends StatelessWidget { ), icon: const Icon(Icons.arrow_right_alt), label: const Text('Start Quiz'), - ), + ) ], ), );