Flutter

Framework สำหรับสร้างแอป cross-platform โดย Google เขียนด้วยภาษา Dart ตัวเดียวแล้วรันได้ทั้ง Android, iOS, Web, Desktop

จุดเด่น

  • ไม่ใช่ภาษาโปรแกรมมิ่ง — เป็น framework ที่ใช้ภาษา Dart
  • Compile เป็น native ARM machine code โดยตรง (ไม่ผ่าน interpreter หรือ bridge)
  • ทุกอย่างใน Flutter คือ Widgets — เป็น building blocks ของ UI ทั้งหมด
  • เขียนโค้ด Dart ตัวเดียว → ได้ทั้ง iOS, Android, Web, Desktop

แพลตฟอร์มที่รองรับ

แพลตฟอร์มสถานะหมายเหตุ
iOS & Androidหลักรองรับดีที่สุด
Webรองใช้ features ของ modern browser
Windows, macOS, LinuxรองDesktop apps

ข้อจำกัด: iOS/macOS apps → build ได้บน macOS เท่านั้น (ต้องลง Xcode) / Android/Web → build ได้บน ทุก OS

Flutter App เริ่มทำงานยังไง

graph LR
  A["main()"] -->|"Dart เรียกอัตโนมัติ"| B["runApp()"]
  B -->|"สั่ง Flutter เริ่ม render"| C[Widget Tree]
  C --> D[แสดงผลบนจอ]
void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        body: Center(
          child: Text("สวัสดี"),
        ),
      ),
    ),
  );
}
Conceptหน้าที่เทียบ Java/Spring
main()จุดเริ่มต้นโปรแกรมpublic static void main()
runApp()สั่ง Flutter เริ่ม render Widget TreeSpringApplication.run()
MaterialAppWidget ราก ให้ Material Design theme@SpringBootApplication
Scaffoldโครงร่างหน้าจอ (body, appBar, drawer)HTML <body>

โครงสร้างโปรเจกต์

my_app/
├── lib/                    ← โค้ด Dart ทั้งหมดอยู่ที่นี่
│   └── main.dart           ← entry point
├── android/ ios/ web/      ← ไฟล์เฉพาะ platform (Flutter จัดการให้)
├── build/                  ← ไฟล์ที่ Flutter สร้างตอน compile (อย่าแก้)
├── test/                   ← Automated tests
├── assets/images/          ← รูปภาพ (ลงทะเบียนใน pubspec.yaml)
├── pubspec.yaml            ← จัดการ dependencies + assets ← สำคัญ!
└── analysis_options.yaml   ← ตั้งค่า linting/code style

Best practice: 1 widget = 1 ไฟล์ ตั้งชื่อแบบ snake_case

Flutter vs Ionic

ด้านFlutterIonic
ภาษาDartHTML/CSS/JavaScript
การแสดงผลCompile เป็น nativeWebView (เหมือนเปิดเว็บในแอป)
ความเร็วเร็ว (native)ช้ากว่า (WebView overhead)
เปรียบเทียบพูดเกาหลีกับคนเกาหลีตรงๆพูดอังกฤษแล้วมีล่ามแปลให้

Widget Lifecycle

3 lifecycle methods สำคัญของ StatefulWidget:

graph LR
  A["initState()"] -->|"ครั้งเดียวตอนสร้าง"| B["build()"]
  B -->|"ทุกครั้งที่ setState()"| B
  B -->|"ก่อน widget ถูกลบ"| C["dispose()"]
class _MyState extends State<MyWidget> {
  @override
  void initState() {     // 1. ทำงานครั้งเดียวตอนสร้าง State
    super.initState();
  }
 
  @override
  Widget build(BuildContext context) {  // 2. ทำงานตอนสร้าง UI + ทุกครั้งที่ setState()
    return Container();
  }
 
  @override
  void dispose() {       // 3. ทำงานก่อน widget ถูกลบ (cleanup)
    super.dispose();
  }
}

Theming — กำหนด style ทั้งแอปจากจุดเดียว

MaterialApp(
  theme: ThemeData().copyWith(
    colorScheme: ColorScheme.fromSeed(
      seedColor: const Color.fromARGB(255, 96, 59, 181),
    ),
    appBarTheme: const AppBarTheme(backgroundColor: ...),
    cardTheme: const CardThemeData(margin: ...),
    textTheme: ThemeData().textTheme.copyWith(
      titleLarge: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
    ),
  ),
  darkTheme: darkTheme,          // Dark mode theme
  themeMode: ThemeMode.system,    // ตาม setting ของ device
);
 
// ใช้ใน widget:
Theme.of(context).colorScheme.primary

Debugging

3 เครื่องมือหลัก ใช้คนละจังหวะ: Error Messages ตอนแอปพัง, Debug Mode ตอนไล่ logic, DevTools ตอนปรับ UI

1. Error Messages — อ่าน error เพื่อหาจุดเริ่มต้น

  • error บนจอแอปเห็น เฉพาะตอน development — production แอปจะ crash เฉยๆ
  • เปิด Debug Console (View → Appearance → Panel) เพื่อดูรายละเอียดเพิ่ม
  • เลื่อนขึ้น ใน Debug Console เสมอ — error จริงอยู่ข้างบนของ stack trace
  • stack trace ส่วนใหญ่เป็น internal ของ Flutter → ข้ามได้ → มองหา บรรทัดที่ highlight → นั่นคือโค้ดของเรา
  • คลิก link ใน stack trace → กระโดดไปบรรทัดที่มีปัญหาได้เลย

2. Debug Mode (F5) — หยุดโค้ดแล้วตรวจค่า

เริ่มแอปด้วย Start Debugging (F5) แทน Run Without Debugging — แอปช้าลงนิดแต่ปลดล็อค debugging features

Featureวิธีใช้ทำอะไร
Breakpointคลิกจุดแดงซ้าย line numberหยุดแอปตรงบรรทัดนั้น
Hoverเลื่อน mouse ไปเหนือตัวแปรดูค่าปัจจุบัน + expand object ได้
Watchคลิกขวาตัวแปร → Add to Watchติดตามค่าตลอดโดยไม่ต้อง hover
Step Overปุ่มที่ 2 บน toolbarเดินโค้ดทีละบรรทัด
Resumeปุ่ม playให้แอปรันต่อจนถึง breakpoint ถัดไป
Call Stackpanel ด้านซ้ายดูว่า method ไหนเรียก method ไหน
Variablespanel ด้านซ้ายดู this, context, properties ทั้งหมด

3. Flutter DevTools — ตรวจ UI + Performance

เปิด: Ctrl+Shift+P → “Flutter DevTools” → Open DevTools in Web Browser

Pageใช้ทำอะไร
Flutter Inspectorดู widget tree, ปรับ layout, ตรวจ properties
Performanceวัด performance (ใช้ Profile mode ไม่ใช่ Debug)
Networkดู HTTP requests ที่แอปส่ง
Loggingดู log messages + errors
App Sizeวิเคราะห์ขนาดแอป

Flutter Inspector ทำอะไรได้:

  • Widget Tree — เห็น UI ทั้งหมดเป็น tree ซ้อนกัน เลือกดูแต่ละ widget
  • Layout Explorer — เห็น width/height + ถ้าเลือก Column/Row ปรับ alignment ได้ realtime ผ่าน dropdown
  • Widget Details Tree — ดู properties ทุกตัว (text, color, size)
  • Select Widget Mode — คลิก widget บนจอแอปตรงๆ → กระโดดไปหาใน tree
  • Guidelines — แสดงเส้น guide ว่าทำไม widget อยู่ตำแหน่งนั้น
  • Highlight Oversized Images — เตือนถ้ารูปใหญ่เกินจำเป็น (เปลือง memory)

Responsive & Adaptive

Responsive — ปรับ layout ตามขนาดจอ

final width = MediaQuery.of(context).size.width;
 
if (width < 600) {
  return Column(children: [chart, expensesList]);     // มือถือแนวตั้ง
} else {
  return Row(children: [
    Expanded(child: chart),
    Expanded(child: expensesList),
  ]);  // แนวนอน/tablet
}

ดูเพิ่มเติม: Responsive Design

Adaptive — ปรับ widget ตาม platform

import 'dart:io';
if (Platform.isIOS) { /* ใช้ Cupertino widgets */ }
if (Platform.isAndroid) { /* ใช้ Material widgets */ }

Flutter Internals — Three Trees

graph LR
  A["Widget Tree<br/>โค้ดที่เราเขียน<br/>immutable สร้างใหม่บ่อย"] --> B["Element Tree<br/>Flutter จัดการ<br/>จับคู่ widget กับ render"]
  B --> C["Render Tree<br/>วาดจริงบนจอ<br/>แก้เฉพาะส่วนที่เปลี่ยน"]

เมื่อ setState() → สร้าง Widget Tree ใหม่ แต่ reuse Element + Render Tree เท่าที่ทำได้ → ประหยัด performance

ตัวอย่าง: แอปจากคอร์ส

แต่ละแอปมีหน้าแยก — สรุปสิ่งที่เรียน, widget tree (Mermaid), code ตัวอย่าง:

  • Dice Roller App — Section 1-2: StatefulWidget, setState, Widget Tree
  • Quiz App — Section 3: Conditional rendering, Lifting State Up, data models
  • Expense Tracker App — Section 5-6: AppBar, Modal, Theme, Responsive, ListView

แอปที่สร้างในคอร์ส

แอปSectionConcepts หลัก
Dice Roller App1-2StatefulWidget, setState, Widget Tree
Quiz App3Conditional rendering, Lifting State Up, data models
Expense Tracker App5-6AppBar, Modal, Theme, Responsive Design, ListView
TODO App7Three Trees, Keys
Meals App8-10Navigation, Riverpod, Animation
Shopping List11-12Form, HTTP, FutureBuilder, Firebase
Favorite Places13Camera, Google Maps, SQLite
Chat App14Firebase Auth, Firestore, Push Notifications

Key Points

  • Flutter compile Dart เป็น native ARM machine code → performance ดี
  • ทุกอย่างบนจอคือ Widgets ซ้อนกันเป็น Widget Tree
  • setState() คือหัวใจของ UI update — บอก Flutter ว่า state เปลี่ยนแล้ว ให้เรียก build() ใหม่
  • const ช่วยประหยัด memory — Dart สร้าง object ก้อนเดียวใช้ร่วมกัน
  • Theme กำหนดจากจุดเดียว (ThemeData) ใช้ได้ทั้งแอป
  • Three Trees ทำให้ Flutter rebuild เฉพาะส่วนที่เปลี่ยน → ประหยัด performance
  • แอปที่ซับซ้อนต้องใช้ State Management (เช่น Riverpod) แทนการส่ง state ผ่าน constructor
  • Dart — ภาษาที่ Flutter ใช้
  • Widgets — building blocks ของ UI
  • Navigation — ระบบเปลี่ยนหน้าจอ
  • State Management — จัดการ state ข้าม widgets
  • Riverpod — state management library
  • Firebase — backend service
  • Animation — สร้าง animation ใน Flutter
  • Responsive Design — ปรับ UI ตามขนาดจอ
  • Three Trees — Widget/Element/Render tree internals
  • Framework — Flutter เป็น UI framework
  • Ionic — ทางเลือกแบบ WebView
  • OOP — Flutter/Dart ใช้แนวคิด OOP เต็มรูปแบบ
  • Quartz — SSG ที่ใช้ deploy Digital Garden เก็บ notes เรื่อง Flutter