MaterialApp คือ widget หลักใน Flutter ที่กำหนดค่า Material Design ให้กับทั้งแอปพลิเคชัน โดยให้การกำหนดค่าแบบรวมศูนย์สำหรับการกำหนดเส้นทาง การกำหนดธีม การแปลภาษา และการนำทาง เพิ่มส่วนประกอบอย่าง Navigator, Theme และ MediaQuery ไปยัง Widget Tree โดยอัตโนมัติ ตาม Flutter API Reference, 2025 MaterialApp เป็น widget ที่จำเป็นสำหรับแอปพลิเคชัน Flutter ที่ใช้ Material Design และกำหนดการตั้งค่าระดับโลกที่พร้อมใช้งานทั่วทั้งแผนผัง widget
ประเด็นสำคัญ
MaterialApp คือ widget ห่อหุ้มที่เริ่มต้น Material Design ในแอปพลิเคชัน Flutter โดยเป็นรากของ Widget Tree และให้ widget ที่สืบทอดเข้าถึงบริการของระบบ ได้แก่ การนำทาง ธีม การสอบถามสื่อ และการแปลภาษา หากไม่มี MaterialApp แอปพลิเคชันจะไม่มีสไตล์ Material มาตรฐานและจะไม่สามารถใช้ widget อย่าง Scaffold, AppBar, FloatingActionButton และ BottomNavigationBar ได้
เมื่อใช้ MaterialApp Flutter จะเพิ่ม widget หลักหลายตัวไปยังรากของแผนผังโดยอัตโนมัติ: Navigator (สแต็กหน้าจอสำหรับการนำทาง), Theme (โทนสีและสไตล์), MediaQuery (ข้อมูลอุปกรณ์), Localizations (สตริงที่แปลแล้ว), Directionality (ทิศทางข้อความ) widget เหล่านี้ถูกนำไปใช้เป็น InheritedWidget และสามารถเข้าถึงได้ผ่าน BuildContext ทุกที่ในแอปพลิเคชัน
การกำหนดค่า MaterialApp ขั้นต่ำต้องการเพียงพารามิเตอร์ home — widget ที่แสดงบนหน้าจอหลัก Flutter จะห่อ home ใน Scaffold โดยอัตโนมัติหากยังไม่ได้เป็น Scaffold ผ่านกลไก WidgetsBinding เมื่อคุณเริ่มแอปพลิเคชันด้วย runApp(MaterialApp(home: MyHomePage())) Flutter จะสร้าง Widget Tree หลักโดยมี MaterialApp เป็นราก
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "My Application",
theme: ThemeData(
primarySwatch: Colors.blue,
fontFamily: "Roboto",
),
darkTheme: ThemeData(
brightness: Brightness.dark,
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
ในตัวอย่างนี้ MaterialApp กำหนดค่าธีมพื้นฐาน (สว่างและมืด) ชื่อเรื่อง และหน้าจอหลัก พารามิเตอร์ title ใช้สำหรับชื่อเรื่องของหน้าต่าง (บนเดสก์ท็อป) และสำหรับการเข้าถึง พารามิเตอร์ theme และ darkTheme กำหนดลักษณะที่ปรากฏของแอปพลิเคชันในโหมดต่างๆ
MaterialApp รองรับพารามิเตอร์มากกว่า 30 รายการ ซึ่งแบ่งออกเป็นหมวดหมู่: การตั้งค่า Material Design, การกำหนดเส้นทาง, การกำหนดธีม, การแปลภาษา, การจัดการข้อผิดพลาด และการตั้งค่าเฉพาะแพลตฟอร์ม การรู้จักพารามิเตอร์หลักช่วยให้คุณกำหนดค่าแอปพลิเคชันได้อย่างยืดหยุ่นโดยไม่ต้องเขียนโค้ดเพิ่มเติม
พารามิเตอร์ title กำหนดชื่อแอปพลิเคชันสำหรับชื่อเรื่องหน้าต่างและการเข้าถึง color กำหนดสีของแอปพลิเคชันสำหรับตัวสลับงานบน Android debugShowCheckedModeBanner ซ่อนแบนเนอร์โหมดดีบักในบิลด์ที่เผยแพร่ showPerformanceOverlay เปิดใช้งานการซ้อนทับด้วยข้อมูลประสิทธิภาพ supportDarkTheme ระบุว่าแอปพลิเคชันรองรับธีมมืดหรือไม่
MaterialApp มีพารามิเตอร์สำหรับกำหนดค่าพฤติกรรมบนแพลตฟอร์มต่างๆ: restorationScopeId สำหรับรักษาสถานะแอปพลิเคชันเมื่อรีสตาร์ทบน Android, scrollBehavior สำหรับกำหนดค่าพฤติกรรมการเลื่อนบนระบบปฏิบัติการต่างๆ, useMaterial3 สำหรับเปิดใช้งาน Material 3 (Material You) Material 3 เพิ่มสีแบบไดนามิก ส่วนประกอบใหม่ และสไตล์ที่ได้รับการอัปเดต
| พารามิเตอร์ | ประเภท | วัตถุประสงค์ |
|---|---|---|
| title | String | ชื่อเรื่องหน้าต่างแอปพลิเคชัน |
| theme | ThemeData | การกำหนดค่าธีมสว่าง |
| darkTheme | ThemeData | การกำหนดค่าธีมมืด |
| home | Widget | หน้าจอหลักของแอปพลิเคชัน |
| routes | Map<String, WidgetBuilder> | แผนที่ของเส้นทางที่มีชื่อ |
| locale | Locale | การตั้งค่าภูมิภาคบังคับของแอปพลิเคชัน |
การกำหนดธีม เป็นหนึ่งในพารามิเตอร์หลักของ MaterialApp พารามิเตอร์ theme รับวัตถุ ThemeData ที่กำหนดจานสี การพิมพ์ รูปร่างของส่วนประกอบ และสัญลักษณ์สำหรับธีมสว่าง พารามิเตอร์ darkTheme คือการกำหนดค่าที่เทียบเท่าสำหรับธีมมืด Flutter จะเปลี่ยนธีมโดยอัตโนมัติตามการตั้งค่าระบบของอุปกรณ์
ThemeData ประกอบด้วย primarySwatch (สีหลัก), colorScheme (โทนสีแบบขยายของ Material 3), brightness (สว่างหรือมืด), fontFamily (แบบอักษรเริ่มต้น), textTheme (สไตล์ข้อความ), cardTheme, appBarTheme, buttonTheme และพารามิเตอร์อื่นๆ อีกมากมายสำหรับปรับแต่งส่วนประกอบเฉพาะ ใช้ colorScheme สำหรับ Material 3 และ primarySwatch สำหรับ Material 2
Material 3 (Material You) รองรับ สีแบบไดนามิก ซึ่งดึงมาจากวอลเปเปอร์ของอุปกรณ์บน Android 12+ หากต้องการเปิดใช้งาน ให้ตั้งค่า useMaterial3: true และใช้ colorScheme.fromSeed หรือ colorScheme.fromImageProvider สีแบบไดนามิกจะสร้างจานสีที่กลมกลืนกัน 5 โทนโดยอัตโนมัติ: primary, secondary, tertiary, neutral และ neutralVariant
widget ใดๆ สามารถเข้าถึงธีมปัจจุบันได้ผ่าน Theme.of(context) Theme.of ส่งคืนวัตถุ ThemeData ซึ่งคุณสามารถรับ colors, textTheme และพารามิเตอร์อื่นๆ หากต้องการติดตามการเปลี่ยนแปลงธีม (เช่น เมื่อสลับระหว่างโหมดสว่างและมืด) ให้ใช้บริบทภายในเมธอด build — Flutter จะสร้าง widget ใหม่โดยอัตโนมัติเมื่อธีมเปลี่ยนแปลง
Container(
color: Theme.of(context).colorScheme.primary,
child: Text(
"Themed text example",
style: Theme.of(context).textTheme.headlineMedium,
),
)
ในตัวอย่างนี้ Theme.of(context) รับธีมปัจจุบันจาก MaterialApp ที่ใกล้ที่สุด สีพื้นหลังและสไตล์ข้อความจะตรงกับธีมปัจจุบัน (สว่างหรือมืด) โดยอัตโนมัติ เมื่อธีมเปลี่ยน Container และ Text จะถูกสร้างขึ้นใหม่ด้วยค่าจาก ThemeData ที่อัปเดต
MaterialApp รวม Navigator — ตัวนำทางแบบสแต็กที่จัดการการเปลี่ยนระหว่างหน้าจอต่างๆ พารามิเตอร์ initialRoute, routes และ onGenerateRoute กำหนดวิธีที่ Flutter จัดการการนำทาง Navigator.push และ Navigator.pushReplacement อนุญาตให้เปลี่ยนหน้าจอโดยทางโปรแกรม ในขณะที่ Navigator.pop อนุญาตให้ย้อนกลับ
พารามิเตอร์ routes รับ Map<String, WidgetBuilder> โดยที่คีย์คือชื่อเส้นทาง (สตริง) และค่าคือฟังก์ชันที่สร้าง widget สำหรับหน้าจอนั้น เส้นทางที่มีชื่อสะดวกสำหรับการนำทางแบบคงที่: '/' (เส้นทางหลัก) มักตรงกับ home, '/settings', '/profile' — หน้าจออื่นๆ Navigator.pushNamed(context, '/settings') นำทางไปยังหน้าจอการตั้งค่า
onGenerateRoute คือฟังก์ชันที่ถูกเรียกเมื่อไม่พบเส้นทางใน routes โดยรับ RouteSettings และส่งคืน MaterialPageRoute วิธีการนี้มีประโยชน์สำหรับการนำทางแบบไดนามิกเมื่อเส้นทางขึ้นอยู่กับข้อมูล (เช่น /user/42) onGenerateRoute จะแยกวิเคราะห์ชื่อเส้นทาง ดึงพารามิเตอร์ และสร้างหน้าจอที่เหมาะสม
เพื่อรองรับ ลิงก์ลึก (deep links) ให้ใช้พารามิเตอร์ onGenerateInitialRoute และ onGenerateRoute ร่วมกัน ลิงก์ลึกช่วยให้เปิดหน้าจอเฉพาะของแอปพลิเคชันผ่าน URL (เช่น https://example.com/promo) Flutter จัดการลิงก์ลึกบน Android (ผ่าน intent filters) และ iOS (ผ่าน universal links) และส่งเส้นทางไปยัง onGenerateRoute
MaterialApp(
initialRoute: "/",
routes: {
"/": (context) => const HomePage(),
"/settings": (context) => const SettingsPage(),
},
onGenerateRoute: (settings) {
if (settings.name?.startsWith("/user/") == true) {
final userId = settings.name!.split("/").last;
return MaterialPageRoute(
builder: (_) => UserPage(userId: userId),
);
}
return null;
},
)
ในตัวอย่างนี้ onGenerateRoute จัดการเส้นทางแบบไดนามิกเช่น /user/42 หากไม่พบเส้นทางใน routes แบบคงที่และไม่ตรงกับรูปแบบไดนามิก Flutter จะแสดงหน้าแสดงข้อผิดพลาด ซึ่งสามารถปรับแต่งได้ผ่าน onUnknownRoute
MaterialApp รองรับการแปลภาษาในตัวผ่านพารามิเตอร์ localizationsDelegates และ supportedLocales LocalizationsDelegates โหลดสตริงที่แปลแล้ว และ supportedLocales กำหนดว่าภาษาใดที่แอปพลิเคชันรองรับ Flutter จะตรวจจับภาษาของอุปกรณ์โดยอัตโนมัติและโหลดทรัพยากรที่แปลแล้วที่เกี่ยวข้อง
พารามิเตอร์ supportedLocales รับรายการของ Locale ที่แอปพลิเคชันรองรับ: [const Locale('en'), const Locale('ru'), const Locale('de')] localizationsDelegates คือรายการของผู้รับมอบสิทธิ์ที่โหลดสตริงที่แปลแล้ว สำหรับ Material Design ให้เพิ่ม GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate และ GlobalCupertinoLocalizations.delegate
ในการแปลสตริงของคุณเอง ให้ใช้คลาส AppLocalizations ซึ่งสร้างขึ้นผ่าน flutter_localizations หรือแพ็คเกจ intl AppLocalizations มีเมธอดแบบคงที่สำหรับเข้าถึงสตริงที่แปลแล้ว: AppLocalizations.of(context)!.helloMessage MaterialApp จะส่ง Localizations ไปยัง Widget Tree โดยอัตโนมัติ ทำให้เข้าถึงได้ผ่านบริบท
Flutter มี widget หลักสามแบบสำหรับแพลตฟอร์มต่างๆ: MaterialApp (Material Design สำหรับ Android และเว็บ), CupertinoApp (สไตล์ iOS) และ WidgetsApp (widget พื้นฐานไม่มีสไตล์) การเลือก widget หลักจะกำหนดลักษณะที่ปรากฏของทั้งแอปพลิเคชันและความพร้อมใช้งานของส่วนประกอบเฉพาะแพลตฟอร์ม
MaterialApp เหมาะสำหรับแอปพลิเคชันส่วนใหญ่ด้วยการรองรับ Material Design ซึ่งดูดีทั้งบน Android เว็บ และเดสก์ท็อป Material Design มีไลบรารีส่วนประกอบที่หลากหลาย: Scaffold, AppBar, BottomNavigationBar, Drawer, SnackBar, Dialog และอื่นๆ อีกมากมาย MaterialApp ยังรองรับ Material 3 ด้วยสีแบบไดนามิก
CupertinoApp ใช้ Cupertino Design ซึ่งเป็นไปตามหลักเกณฑ์ Human Interface Guidelines ของ Apple โดยมี CupertinoPageScaffold, CupertinoNavigationBar, CupertinoTabBar และส่วนประกอบสไตล์ iOS อื่นๆ ใช้ CupertinoApp สำหรับแอปพลิเคชัน iOS หรือแอปพลิเคชันที่ใช้สไตล์ Apple บนทุกแพลตฟอร์ม
WidgetsApp คือ widget หลักพื้นฐานที่ไม่มีสไตล์ โดยเพิ่ม Navigator, MediaQuery และ Localizations แต่ไม่มีธีมหรือส่วนประกอบ Material/Cupertino WidgetsApp เหมาะสำหรับระบบการออกแบบที่กำหนดเอง เกม หรือแอปพลิเคชันที่มีสไตล์ของตัวเองซึ่ง Material หรือ Cupertino มากเกินไป
| widget หลัก | ระบบการออกแบบ | เมื่อใดควรใช้ |
|---|---|---|
| MaterialApp | Material Design (Google) | Android, เว็บ, เดสก์ท็อป, แอปพลิเคชันข้ามแพลตฟอร์ม |
| CupertinoApp | Cupertino (Apple HIG) | แอปพลิเคชัน iOS, สไตล์ Apple บนทุกแพลตฟอร์ม |
| WidgetsApp | ไม่มีสไตล์ | การออกแบบที่กำหนดเอง, เกม, ระบบการออกแบบของตัวเอง |
คำถามที่พบบ่อย
ไม่จำเป็น — คุณสามารถใช้ CupertinoApp สำหรับสไตล์ iOS หรือ WidgetsApp สำหรับการออกแบบที่กำหนดเอง MaterialApp จำเป็นหากคุณใช้ widget ของ Material: Scaffold, AppBar, FloatingActionButton และอื่นๆ
ใช้พารามิเตอร์ theme (ธีมสว่าง) และ darkTheme (ธีมมืด) Flutter จะเปลี่ยนธีมโดยอัตโนมัติตามการตั้งค่าระบบ หากต้องการบังคับเปลี่ยน ให้ใช้ WidgetsBinding.instance.platformDispatcher.platformBrightness
ได้ โดยค่าเริ่มต้น useMaterial3 เป็น false และ MaterialApp ใช้ Material 2 หากต้องการเปิดใช้งาน Material 3 ให้ตั้งค่า useMaterial3: true และใช้ colorScheme จาก ColorScheme.fromSeed
ใช้พารามิเตอร์ onUnknownRoute ซึ่งรับ RouteSettings และส่งคืน MaterialPageRoute หากทั้ง routes และ onGenerateRoute ไม่ได้จัดการเส้นทาง onUnknownRoute จะถูกเรียก — ให้ส่งคืนหน้าที่มีข้อความแสดงข้อผิดพลาด
หากไม่ระบุพารามิเตอร์ home และไม่มี routes Flutter จะแสดงข้อยกเว้นเมื่อเริ่มทำงาน คุณต้องระบุอย่างน้อยหนึ่งอย่างจาก: home, routes ที่มีเส้นทาง '/' หรือ initialRoute
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ