Navigation

ระบบเปลี่ยนหน้าจอใน Flutter — ใช้ stack (ซ้อนทับ) โดย push หน้าใหม่ขึ้นไป และ pop กลับมาหน้าเดิม

// ไปหน้าใหม่ (push ขึ้น stack)
Navigator.of(context).push(
  MaterialPageRoute(builder: (ctx) => MealDetailScreen(meal: meal)),
);
 
// กลับหน้าเดิม (pop ออกจาก stack)
Navigator.of(context).pop();

ส่งข้อมูลกลับตอน pop

// หน้าที่ 2 — ส่งข้อมูลกลับ
Navigator.of(context).pop(selectedFilters);
 
// หน้าที่ 1 — รับข้อมูล (ต้อง await)
final result = await Navigator.of(context).push(
  MaterialPageRoute(builder: (ctx) => FiltersScreen()),
);
// result = ข้อมูลที่หน้า 2 ส่งกลับมา

TabBar — แท็บสลับเนื้อหา

DefaultTabController(
  length: 2,
  child: Scaffold(
    appBar: AppBar(
      title: const Text('Meals'),
      bottom: const TabBar(
        tabs: [
          Tab(text: 'Categories'),
          Tab(text: 'Favorites'),
        ],
      ),
    ),
    body: const TabBarView(
      children: [
        CategoriesScreen(),
        FavoritesScreen(),
      ],
    ),
  ),
);
  • DefaultTabController ควบคุม state ของ tab (ตัวไหนถูกเลือก)
  • TabBar แสดงแท็บ / TabBarView แสดงเนื้อหาของแต่ละแท็บ
  • จำนวน tabs ต้องเท่ากับ children ใน TabBarView

Drawer — เมนูด้านข้าง

Scaffold(
  drawer: Drawer(
    child: ListView(
      children: [
        const DrawerHeader(
          decoration: BoxDecoration(color: Colors.purple),
          child: Text('Menu', style: TextStyle(color: Colors.white)),
        ),
        ListTile(
          leading: const Icon(Icons.restaurant),
          title: const Text('Meals'),
          onTap: () { Navigator.of(context).pop(); },  // ปิด drawer
        ),
        ListTile(
          leading: const Icon(Icons.settings),
          title: const Text('Filters'),
          onTap: () {
            Navigator.of(context).push(
              MaterialPageRoute(builder: (ctx) => FiltersScreen()),
            );
          },
        ),
      ],
    ),
  ),
);

InkWell / GestureDetector — จับ tap บน widget

// InkWell — มี ripple effect (Material)
InkWell(
  onTap: () { selectMeal(context); },
  child: Card(child: ...),
);
 
// GestureDetector — จับ gesture ทุกประเภท ไม่มี visual feedback
GestureDetector(
  onTap: () { ... },
  onLongPress: () { ... },
  child: Container(...),
);

PopScope — ดักจับปุ่ม back

PopScope(
  canPop: false,          // ห้ามกด back ออก
  onPopInvoked: (didPop) {
    // ทำอะไรบางอย่างก่อนออก
  },
  child: Scaffold(...),
);

Key Points

  • Navigation ใช้ stack — push เพิ่มหน้า, pop กลับหน้าเดิม
  • ส่งข้อมูลไปหน้าใหม่ผ่าน constructor / ส่งกลับผ่าน pop(data)
  • TabBar สำหรับสลับเนื้อหาในหน้าเดียว
  • Drawer สำหรับเมนูหลักของแอป
  • InkWell ทำให้ widget ที่ไม่ใช่ปุ่มกดได้ + มี ripple effect
  • Flutter — framework ที่มีระบบ Navigation
  • Widgets — TabBar, Drawer, InkWell เป็น widgets
  • State Management — navigation กับ state มักทำงานร่วมกัน