Navigator คือวิดเจ็ตจัดการการนำทางใน Flutter ที่จัดการสแต็กของออบเจ็กต์ Route เพื่อเคลื่อนที่ระหว่างหน้าจอผ่านเมธอด push, pop, pushReplacement และ pushNamed ซึ่งแตกต่างจากการแทนที่วิดเจ็ตโดยตรงผ่าน State Navigator ทำงานในระดับของทั้งหน้าจอ: มันเก็บประวัติการเปลี่ยนหน้าและรองรับแอนิเมชันเฉพาะแพลตฟอร์ม ตาม Flutter API Reference (2026) แล้ว Navigator 2.0 (Router) ให้การจัดการการนำทางแบบประกาศสำหรับสถานการณ์ที่ซับซ้อนด้วยลิงก์ลึกและการออกแบบที่ปรับเปลี่ยนได้ ในแอปพลิเคชันทั่วไป Navigator รับประกันพฤติกรรมที่ถูกต้องของปุ่มกลับบน Android และท่าทางการปัดบน iOS
ประเด็นสำคัญ
Navigator คือวิดเจ็ตที่จัดการสแต็กของออบเจ็กต์ Route ซึ่งนำทางการนำทางหน้าจอในแอปพลิเคชัน Flutter แต่ละครั้งที่เรียก push จะวาง Route ใหม่บนยอดของสแต็ก pop จะลบ Route บนสุดและกลับไปยังหน้าจอก่อนหน้า MaterialApp จะสร้าง Navigator โดยอัตโนมัติสำหรับทั้งแอปพลิเคชัน ทำให้เข้าถึงได้ผ่าน Navigator.of(context)
ซึ่งแตกต่างจาก StatefulWidget ที่การแทนที่เนื้อหาเกิดขึ้นผ่าน setState ภายในวิดเจ็ตเดียว Navigator ดำเนินการกับทั้งหน้าจอที่มีวงจรชีวิตของตัวเอง แต่ละ Route ในสแต็กเป็นสถานะที่แยกออกจากกันด้วย BuildContext ของตัวเอง ซึ่งป้องกันการรั่วไหลของหน่วยความจำและทำให้การจัดการการพึ่งพาง่ายขึ้น เมื่อเรียก pop Route ที่ไม่ได้ใช้จะถูกทำลายและปล่อยทรัพยากร
ตาม Flutter Navigation Guide (2026) แล้ว Navigator ได้วิวัฒนาการจาก API แบบจำเป็น (Navigator 1.0) เป็นแบบประกาศ (Navigator 2.0) Navigator 1.0 ใช้เมธอด push/pop โดยตรง ซึ่งสะดวกสำหรับสถานการณ์ง่ายๆ Navigator 2.0 (Router) เหมาะสำหรับแอปพลิเคชันที่มีลิงก์ลึก การนำทางแบบปรับเปลี่ยนได้ และการกำหนดเส้นทางบนเว็บ
ภายใน Navigator ใช้ Overlay — วิดเจ็ตพิเศษที่แสดง Routes ซ้อนทับกัน แต่ละ Route สร้างตำแหน่งของตัวเองใน Overlay ด้วย z-index ที่สอดคล้องกับความลึกในสแต็ก ซึ่งอธิบายว่าทำไมเมื่อเรียก push หน้าจอใหม่จะแสดงแอนิเมชันทับหน้าจอก่อนหน้า และเมื่อเรียก pop หน้าจอก่อนหน้าจะพร้อมแสดง: มันไม่ได้ถูกทำลาย แต่ยังคงอยู่ใน Overlay ใต้หน้าจอใหม่
สำหรับแอนิเมชันการเปลี่ยนหน้า Navigator ใช้ PageTransitionsTheme ซึ่งสามารถแทนที่ใน ThemeData แอนิเมชันเฉพาะแพลตฟอร์มถูกกำหนดผ่าน CupertinoPageRoute สำหรับ iOS (เลื่อนจากขวา) และ MaterialPageRoute สำหรับ Android (เลื่อนจากด้านล่าง) Navigator จะเลือกแอนิเมชันที่ถูกต้องโดยอัตโนมัติเมื่อใช้ PlatformRoute
Navigator ให้ชุดของเมธอดสำหรับจัดการสแต็ก Route แต่ละเมธอดแก้ไขงานการนำทางเฉพาะ — จากการเปลี่ยนหน้าอย่างง่ายไปจนถึงการแทนที่ประวัติหน้าจอทั้งหมด มาดูเมธอดหลักพร้อมตัวอย่างการใช้งานกัน
| เมธอด | คำอธิบาย | สถานการณ์การใช้งาน |
|---|---|---|
| push | เพิ่ม Route ที่ยอดของสแต็ก | นำทางไปยังหน้าจอใหม่โดยสามารถกลับมาได้ |
| pop | ลบ Route บนสุดออกจากสแต็ก | กลับไปยังหน้าจอก่อนหน้า |
| pushReplacement | แทนที่ Route ปัจจุบันด้วยอันใหม่ | หลังจากเข้าสู่ระบบ — หน้าจอเข้าสู่ระบบถูกแทนที่ด้วยหน้าจอหลัก |
| pushAndRemoveUntil | เพิ่ม Route และลบก่อนหน้าจนกว่าจะตรงตามเงื่อนไข | ไปยังหน้าจอหลักพร้อมล้างประวัติ |
| popUntil | ลบ Routes จากสแต็กจนกว่าจะตรงตามเงื่อนไข | กลับไปยังหน้าจอที่เฉพาะเจาะจงในประวัติ |
| maybePop | เรียก pop เฉพาะเมื่อสแต็กมี >1 Route | ป้องกันการปิดแอปพลิเคชันเมื่อกดกลับโดยไม่ตั้งใจ |
เมธอด push รับ Route และคืนค่า Future พร้อมผลลัพธ์ที่ส่งระหว่าง pop ซึ่งช่วยให้รับข้อมูลจากหน้าจอที่นำทางไปได้ ตัวอย่างเช่น หน้าจอเลือกวันที่สามารถคืนค่า DateTime ผ่าน Navigator.pop(context, selectedDate) เมธอด pop ที่ไม่มีอาร์กิวเมนต์คืนค่า null และถ้ามีอาร์กิวเมนต์จะส่งค่าไปยังหน้าจอที่เรียก
pushReplacement แทนที่ Route ปัจจุบันด้วยอันใหม่ โดยลบ route ปัจจุบันออกจากสแต็ก ซึ่งสำคัญสำหรับสถานการณ์ที่ผู้ใช้ไม่ควรกลับไปยังหน้าจอก่อนหน้า ตัวอย่างทั่วไป — หน้าจอเข้าสู่ระบบ: หลังจากเข้าสู่ระบบสำเร็จ หน้าจอปัจจุบันจะถูกแทนที่ด้วยหน้าจอหลัก และปุ่มกลับจะไม่กลับไปยังแบบฟอร์มเข้าสู่ระบบ
Navigator รองรับการนำทางโดยเส้นทางที่มีชื่อผ่านเมธอด pushNamed แทนที่จะสร้าง Route โดยตรง นักพัฒนาระบุตัวระบุสตริง และ Navigator จะสร้าง Route โดยอัตโนมัติตามการกำหนดค่าใน MaterialApp ซึ่งทำให้โค้ดง่ายขึ้นและรวมศูนย์การกำหนดเส้นทางในที่เดียว
เส้นทางที่มีชื่อถูกกำหนดผ่านคุณสมบัติ routes ใน MaterialApp โดยที่แต่ละคีย์คือสตริงเส้นทางและค่าคือฟังก์ชันที่คืนค่า Widget สำหรับเส้นทางแบบไดนามิก (พร้อมพารามิเตอร์) จะใช้ onGenerateRoute — callback ที่รับ RouteSettings และคืนค่า Route ซึ่งช่วยให้ส่งอาร์กิวเมนต์ผ่านพารามิเตอร์ arguments และนำทางการนำทางเชิงลึก
ตาม Flutter Cookbook (2026) แล้ว การส่งอาร์กิวเมนต์ผ่าน pushNamed ทำได้ด้วยพารามิเตอร์ arguments: Object? หน้าจอผู้รับจะดึงอาร์กิวเมนต์ผ่าน ModalRoute.of(context)!.settings.arguments ซึ่งให้การถ่ายโอนข้อมูลที่ปลอดภัยชนิดโดยไม่ต้องใช้ตัวแปรส่วนกลางหรือ InheritedWidget
คุณสมบัติ onUnknownRoute ใน MaterialApp จัดการกรณีที่เรียก pushNamed ด้วยเส้นทางที่ไม่มีอยู่ ซึ่งมีประโยชน์สำหรับการแสดงหน้าจอ 404 หรือเปลี่ยนเส้นทางไปยังหน้าแรก เมื่อรวมกับ onGenerateRoute จะรับประกันความครอบคลุมที่สมบูรณ์ของสถานการณ์การนำทางที่เป็นไปได้ทั้งหมด
Navigator 2.0 (หรือที่รู้จักในชื่อ Router API) เป็นวิธีการนำทางแบบประกาศที่นำมาใช้ใน Flutter 2.0 ซึ่งแตกต่างจาก Navigator 1.0 แบบจำเป็นที่นักพัฒนาเรียก push/pop Router จัดการการนำทางผ่านสถานะ โดยซิงโครไนซ์ URL ของเบราว์เซอร์กับหน้าจอปัจจุบันโดยอัตโนมัติ ซึ่งสำคัญโดยเฉพาะสำหรับแอปพลิเคชันเว็บและเวอร์ชันเดสก์ท็อป
สถาปัตยกรรมของ Navigator 2.0 ประกอบด้วยสามองค์ประกอบหลัก: RouteInformationParser แยกวิเคราะห์ URL เป็นการกำหนดค่าเส้นทาง RouterDelegate แปลงการกำหนดค่าเป็นรายการของ Routes และ BackButtonDispatcher จัดการปุ่มกลับของระบบ สถาปัตยกรรมนี้ทำให้การนำทางสามารถคาดเดาได้และทดสอบได้อย่างสมบูรณ์
เพื่อให้การทำงานกับ Navigator 2.0 ง่ายขึ้น มีแพ็กเกจตัวห่อ: go_router (แนะนำโดย Google), auto_route และ beamer go_router ให้ DSL แบบประกาศสำหรับกำหนดเส้นทางด้วยการรองรับการนำทางแบบซ้อน การเปลี่ยนเส้นทาง และลิงก์ลึกโดยไม่ต้องใช้งาน RouterDelegate ด้วยตนเอง ตาม pub.dev (2026) แล้ว go_router ถูกใช้ใน 35% ของโปรเจกต์ Flutter ใหม่ที่ต้องการวิธีการแบบประกาศ
ลองพิจารณาตัวอย่างของ Navigator ด้วยเส้นทางที่มีชื่อและการส่งข้อมูลระหว่างหน้าจอ โค้ดสาธิตหน้าจอรายการสินค้า การเปลี่ยนไปยังหน้าจอรายละเอียด และการกลับมาพร้อมผลลัพธ์
// Route configuration in MaterialApp
MaterialApp(
initialRoute: '/',
onGenerateRoute: (RouteSettings settings) {
if (settings.name == '/') {
return MaterialPageRoute(
builder: (context) => const ProductListPage(),
);
}
if (settings.name == '/product') {
final productId = settings.arguments as String;
return MaterialPageRoute(
builder: (context) => ProductDetailPage(productId: productId),
);
}
return MaterialPageRoute(
builder: (context) => const NotFoundPage(),
);
},
)
// Navigation with data passing
final result = await Navigator.pushNamed(
context,
'/product',
arguments: 'product_42',
);
// Getting data on the receiving screen
final args = ModalRoute.of(context)!.settings.arguments as String;
// Replace screen after login
Navigator.pushReplacementNamed(context, '/home');
// Clear stack to main screen
Navigator.pushNamedAndRemoveUntil(
context,
'/home',
(route) => false,
);
ในตัวอย่าง Navigator.pushNamed ส่ง ID สินค้าไปยังหน้าจอรายละเอียด เมื่อกลับผ่าน Navigator.pop(context, updatedProduct) หน้าจอที่เรียกจะได้รับข้อมูลที่อัปเดตในตัวแปร result pushReplacementNamed แทนที่หน้าจอปัจจุบันหลังจากอนุญาต และ pushNamedAndRemoveUntil ด้วยเงื่อนไข (route) => false จะล้างสแต็กอย่างสมบูรณ์ ป้องกันการนำทางกลับไปยังหน้าจอก่อนหน้า
คำถามที่พบบ่อย
Navigator 1.0 — API แบบจำเป็นที่มีเมธอด push และ pop สะดวกสำหรับแอปพลิเคชันมือถืออย่างง่าย Navigator 2.0 — API แบบประกาศผ่าน Router, RouterDelegate และ RouteInformationParser จำเป็นสำหรับแอปพลิเคชันเว็บที่มีการกำหนดเส้นทาง URL ลิงก์ลึก และการนำทางแบบปรับเปลี่ยนได้ สำหรับโปรเจกต์ที่ใช้งานได้จริง แนะนำให้ใช้ go_router เป็นตัวห่อที่เรียบง่ายเหนือ Navigator 2.0
ข้อมูลถูกส่งผ่านพารามิเตอร์ arguments ใน pushNamed หรือผ่านคอนสตรักเตอร์ของ Route โดยตรง บนหน้าจอผู้รับ ข้อมูลจะถูกดึงผ่าน ModalRoute.of(context)!.settings.arguments ในการส่งข้อมูลกลับ ให้ใช้ Navigator.pop(context, result) — หน้าจอที่เรียกจะได้รับผลลัพธ์เป็นค่า Future ที่คืนจาก push
สิ่งนี้เกิดขึ้นเมื่อหน้าจอปัจจุบันถูกเปิดผ่าน pushReplacement ซึ่งลบ Route ก่อนหน้าออกจากสแต็ก ในกรณีนี้ไม่มีประวัติการนำทางและปุ่มกลับจะปิดแอปพลิเคชัน ในการกลับไป ให้ใช้ push ปกติแทน pushReplacement นอกจากนี้ตรวจสอบว่าการเรียก Navigator.pop ถูกจัดการอย่างถูกต้องบนหน้าจอปัจจุบัน
ใช้ pushReplacement เพื่อแทนที่หน้าจอปัจจุบันด้วยหน้าจอใหม่ — หน้าจอก่อนหน้าจะถูกลบออกจากสแต็กและไม่สามารถกลับไปได้ สำหรับการล้างประวัติทั้งหมด ให้ใช้ pushAndRemoveUntil ด้วยเงื่อนไข (route) => false หรือคุณสามารถแทนที่ WillPopScope (เลิกใช้แล้ว) หรือ PopScope เพื่อสกัดกั้นปุ่มกลับของระบบ
go_router คือแพ็กเกจการนำทางแบบประกาศจาก Google ที่สร้างบน Navigator 2.0 มันให้ DSL ง่ายๆ สำหรับกำหนดเส้นทางด้วยการรองรับการซ้อน การเปลี่ยนเส้นทาง ลิงก์ลึก และ ShellRoute สำหรับ BottomNavigationBar ใช้ go_router สำหรับโปรเจกต์ใหม่ โดยเฉพาะอย่างยิ่งหากต้องการการรองรับเว็บหรือรูปแบบการนำทางที่ซับซ้อนด้วยเส้นทางที่ป้องกัน
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ