Flutter
Framework สำหรับสร้างแอป cross-platform โดย Google เขียนด้วยภาษา Dart ตัวเดียวแล้วรันได้ทั้ง Android และ iOS
จุดเด่น
- ไม่ใช่ภาษาโปรแกรมมิ่ง — เป็น framework ที่ใช้ภาษา Dart
- Compile เป็น native ARM machine code โดยตรง (ไม่ผ่าน interpreter หรือ bridge)
- ทุกอย่างใน Flutter คือ Widgets — เป็น building blocks ของ UI ทั้งหมด
- เขียนโค้ด Dart ตัวเดียว → ได้ทั้ง iOS, Android, Web, Desktop
Flutter App เริ่มทำงานยังไง
ขั้นที่ 1 → main() ถูก Dart เรียกอัตโนมัติ
ขั้นที่ 2 → runApp() สั่ง Flutter เริ่ม render
ขั้นที่ 3 → ส่ง Widget Tree เข้าไป → แสดงผลบนจอ
void main() {
runApp(
MaterialApp(
home: Scaffold(
body: Center(
child: Text("สวัสดี"),
),
),
),
);
}| Concept | หน้าที่ | เทียบ Java/Spring |
|---|---|---|
main() | จุดเริ่มต้นโปรแกรม | public static void main() |
runApp() | สั่ง Flutter เริ่ม render Widget Tree | SpringApplication.run() |
MaterialApp | Widget ราก ให้ Material Design theme | @SpringBootApplication |
Scaffold | โครงร่างหน้าจอ (body, appBar, drawer) | HTML <body> |
Flutter vs Ionic
| ด้าน | Flutter | Ionic |
|---|---|---|
| ภาษา | Dart | HTML/CSS/JavaScript |
| การแสดงผล | Compile เป็น native | WebView (เหมือนเปิดเว็บในแอป) |
| ความเร็ว | เร็ว (native) | ช้ากว่า (WebView overhead) |
| เปรียบเทียบ | พูดเกาหลีกับคนเกาหลีตรง ๆ | พูดอังกฤษแล้วมีล่ามแปลให้ |
โครงสร้างโปรเจกต์
lib/
├── main.dart ← จุดเริ่มต้น: runApp() + MaterialApp
├── gradient_container.dart ← StatelessWidget
├── dice_roller.dart ← StatefulWidget
└── styled_text.dart ← Reusable Widget
assets/
└── images/ ← รูปภาพ (ลงทะเบียนใน pubspec.yaml)
Best practice: 1 widget = 1 ไฟล์ ตั้งชื่อแบบ snake_case
ตัวอย่าง: Dice Roller App
แอปทอยลูกเต๋าจากคอร์ส Academind — ใช้แนวคิดหลักของ Flutter ครบ
Widget Tree
MaterialApp
└── Scaffold
└── GradientContainer (StatelessWidget)
└── Container + LinearGradient
└── Center
└── DiceRoller (StatefulWidget)
└── Column
├── Image.asset (รูปลูกเต๋า)
├── SizedBox (เว้นระยะ)
└── TextButton → "Roll Dice"
Flow เมื่อกดปุ่ม (setState)
กดปุ่ม "Roll Dice"
↓
onPressed เรียก rollDice()
↓
setState() → currentDiceRoll = สุ่มเลขใหม่ (1–6)
↓
Flutter เรียก build() ใหม่
↓
Image.asset('dice-$currentDiceRoll.png') โหลดรูปใหม่
↓
จอ update!
โค้ดหลัก (StatefulWidget + setState)
final randomizer = Random();
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 = randomizer.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 StyledText("Roll Dice"),
),
],
);
}
}Concepts ที่ใช้ในตัวอย่างนี้: StatefulWidget 2 classes, setState(), Random(), String Interpolation $, Functions as Values, Named Constructors, const
Key Points
- Flutter compile Dart เป็น native ARM machine code → performance ดี
- ทุกอย่างบนจอคือ Widgets ซ้อนกันเป็น Widget Tree
setState()คือหัวใจของ UI update — บอก Flutter ว่า state เปลี่ยนแล้ว ให้เรียกbuild()ใหม่constช่วยประหยัด memory — Dart สร้าง object ก้อนเดียวใช้ร่วมกัน- Best practice: 1 widget = 1 ไฟล์, ตั้งชื่อ
snake_case