Quiz App
แอป quiz จากคอร์ส Flutter Academind Section 3 — แอปที่สอนเรื่อง conditional rendering, การส่ง data ระหว่าง widget, และ data models
Widget Tree
graph TD MaterialApp --> Quiz["Quiz (StatefulWidget)"] Quiz -->|"activeScreen == start"| StartScreen Quiz -->|"activeScreen == questions"| QuestionsScreen Quiz -->|"activeScreen == results"| ResultsScreen StartScreen --> Col1["Column + Image + OutlinedButton"] QuestionsScreen --> Col2["Column + Text + ...AnswerButton"] ResultsScreen --> Scroll["SingleChildScrollView"] Scroll --> Col3["Column + QuestionsSummary + TextButton"]
Flow ของแอป
graph LR A[StartScreen] -->|"กดปุ่ม Start Quiz"| B[QuestionsScreen] B -->|"ตอบครบทุกข้อ"| C[ResultsScreen] C -->|"กดปุ่ม Restart"| A
สิ่งที่เรียนจาก Section 3
Conditional Rendering
- switchScreen — ใช้ตัวแปร
activeScreenเลือกแสดง widget ต่างกัน - Collection if —
if (condition) Widget()ในchildren: [] - Ternary —
condition ? WidgetA() : WidgetB()
Lifting State Up
- Lifting State Up — Quiz (parent) เก็บ
activeScreen+selectedAnswers - ส่ง callback function ลงไปให้ child (เช่น
onSelectAnswer) - child เรียก callback → parent
setState()→ เปลี่ยนหน้าจอ
Data Models
- QuizQuestion class — เก็บ
text+answers - Getter
shuffledAnswers—List.of()copy ก่อนshuffle()ไม่แก้ต้นฉบับ - List<Map<String, Object>> — summary data เก็บคำถาม + คำตอบ user + คำตอบถูก
Collections & Functional
- map() — แปลง list → list ของ widget (
answers.map((a) => AnswerButton(...))) - where() — filter เฉพาะข้อที่ตอบถูก (
summaryData.where((d) => ...)) - Spread operator
...— แกะ list ใส่ในchildren: [] - toList() — แปลง Iterable → List (เพราะ
childrenต้องเป็น List) - Arrow function
=>— ใช้แทน{ return ... }เมื่อ body สั้น
Widgets ที่ใช้
- Expanded — ใช้ใน Row เพื่อให้ Column ไม่ overflow
- SingleChildScrollView — scroll ได้เมื่อเนื้อหาเกินจอ
- OutlinedButton / OutlinedButton.icon() — ปุ่ม answer + ปุ่ม restart
- Icon —
Icons.arrow_right_altข้างปุ่ม restart
Patterns สำคัญ
- Anonymous functions —
onPressed: () { chooseAnswer(answer); } - initState() — เริ่ม state ตอน widget สร้างครั้งแรก
- ส่ง function เป็น argument —
void Function(String answer) onSelectAnswer
Key Points
- Conditional rendering เลือกแสดง widget ตามเงื่อนไข — ไม่ต้องสร้างหลายหน้า
- Lifting State Up = ย้าย state ขึ้น parent เพื่อ share ระหว่าง children
map()+ spread...คือ pattern หลักในการสร้าง dynamic widget list- Getter (
get shuffledAnswers) เรียกเหมือน property แต่ compute ทุกครั้ง List.of()copy list ก่อนshuffle()เพื่อไม่แก้ต้นฉบับ (เพราะfinalล็อคแค่ reference)
Related
- Flutter — framework ที่ใช้สร้างแอปนี้
- Widgets — reference ของทุก widget ที่ใช้
- Dart — ภาษาที่เขียน (map, where, spread, getter, arrow function)
- Lifting State Up — pattern หลักที่เรียนใน section นี้
- Dice Roller App — แอปก่อนหน้า Section 1-2
- Expense Tracker App — แอปถัดไป Section 5-6
- Flutter Academind Complete — สรุปคอร์สทั้งหมด