Dice Roller App
แอปทอยลูกเต๋าจากคอร์ส Flutter Academind Section 1-2 — แอปแรกสุดที่สร้าง ใช้แนวคิดพื้นฐานของ Flutter ครบ
Widget Tree
graph TD MaterialApp --> GradientContainer["GradientContainer (StatelessWidget)"] GradientContainer --> Container["Container + BoxDecoration"] Container --> Center Center --> DiceRoller["DiceRoller (StatefulWidget)"] DiceRoller --> Column Column --> Image["Image.asset (dice)"] Column --> SizedBox["SizedBox (spacing)"] Column --> TextButton["TextButton (Roll Dice)"]
Flow เมื่อกดปุ่ม (setState)
graph TD A["กดปุ่ม Roll Dice"] --> B["onPressed เรียก rollDice()"] B --> C["setState() → สุ่มเลขใหม่ 1–6"] C --> D["Flutter เรียก build() ใหม่"] D --> E["Image.asset โหลดรูปใหม่"] E --> F["จอ update!"]
สิ่งที่เรียนจาก Section 1-2
Flutter Basics
- Widget Tree — ทุกอย่างบนจอคือ Widgets ซ้อนกัน (
child:/children:) - MaterialApp → Scaffold → Column — โครงสร้างพื้นฐานของทุกแอป
- StatelessWidget — widget ที่ไม่เปลี่ยนหลังสร้าง (เช่น GradientContainer)
- StatefulWidget — widget ที่เปลี่ยนได้ด้วย
setState()(เช่น DiceRoller) - ทำไมต้อง 2 class — Widget class ถูกสร้างใหม่บ่อย แต่ State class อยู่ถาวรเก็บข้อมูล
Dart Basics
- var / final / const —
const > final > varใช้ตัวเข้มงวดที่สุด - Functions as values — ส่ง function เป็น argument (
onPressed: rollDice) - String interpolation —
'dice-$currentDiceRoll.png' - Named arguments —
{required this.text}/{super.key} - Private —
_prefix แทน keywordprivate - Named constructors —
GradientContainer.purple() - super.key — ส่ง key ให้ parent class สำหรับ widget identity
Widgets ที่ใช้
- Container + BoxDecoration + LinearGradient — พื้นหลังไล่สี
- Center — จัดลูกไว้ตรงกลาง
- Column — จัดลูกแนวตั้ง
- Image.asset() — แสดงรูปลูกเต๋าจาก assets
- SizedBox — เว้นระยะระหว่าง widget
- TextButton — ปุ่มกด Roll Dice
- const — ประหยัด memory (Dart cache object ก้อนเดียวใช้ซ้ำ)
โค้ดหลัก
class DiceRoller extends StatefulWidget {
const DiceRoller({super.key});
@override
State<DiceRoller> createState() => _DiceRollerState();
}
class _DiceRollerState extends State<DiceRoller> {
var currentDiceRoll = 2;
void rollDice() {
setState(() {
currentDiceRoll = Random().nextInt(6) + 1;
});
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Image.asset('assets/images/dice-$currentDiceRoll.png', width: 200),
const SizedBox(height: 20),
TextButton(onPressed: rollDice, child: const Text('Roll Dice')),
],
);
}
}Key Points
- แอปแรกสุด — เข้าใจ Widget Tree, StatelessWidget vs StatefulWidget
setState()คือหัวใจของ UI update: เปลี่ยน state → Flutter เรียกbuild()ใหม่ → จอ update- ทุก Widget ต้องมี
build()method ที่ return widget tree constใส่ได้ทุกที่ที่ค่าไม่เปลี่ยน → ประหยัด memory- Dart basics: var/final/const, functions as values, string interpolation, named arguments
Related
- Flutter — framework ที่ใช้สร้างแอปนี้
- Widgets — reference ของทุก widget ที่ใช้
- Dart — ภาษาที่เขียน (var/final/const, functions, classes)
- Quiz App — แอปถัดไป Section 3
- Flutter Academind Complete — สรุปคอร์สทั้งหมด