MaterialApp — to główny widżet we Flutterze, który konfiguruje Material Design dla całej aplikacji. Zapewnia scentralizowaną konfigurację routingu, motywów, lokalizacji i nawigacji, automatycznie dodając do Widget Tree takie komponenty jak Navigator, Theme i MediaQuery. Według Flutter API Reference, 2025, MaterialApp jest obowiązkowym widżetem dla każdej aplikacji Flutter używającej Material Design i ustawia globalne opcje dostępne w całym drzewie widżetów.
Najważniejsze
MaterialApp — to widżet-opakowanie, który inicjalizuje Material Design w aplikacji Flutter. Jest korzeniem Widget Tree i zapewnia widżetom potomnym dostęp do usług systemowych: nawigacji, motywów, zapytań medialnych i lokalizacji. Bez MaterialApp aplikacja nie będzie mieć standardowego stylu Material i nie będzie mogła używać takich widżetów jak Scaffold, AppBar, FloatingActionButton i BottomNavigationBar.
Podczas używania MaterialApp Flutter automatycznie dodaje kilka kluczowych widżetów do korzenia drzewa: Navigator (stos ekranów do nawigacji), Theme (schemat kolorów i style), MediaQuery (informacje o urządzeniu), Localizations (zlokalizowane ciągi znaków), Directionality (kierunek tekstu). Te widżety są zaimplementowane jako InheritedWidget i są dostępne przez BuildContext w dowolnym miejscu aplikacji.
Minimalna konfiguracja MaterialApp wymaga tylko parametru home — widżetu wyświetlanego na głównym ekranie. Flutter automatycznie owija home w Scaffold, jeśli nie jest on Scaffold, przez mechanizm WidgetsBinding. Przy uruchomieniu aplikacji z runApp(MaterialApp(home: MyHomePage())) Flutter tworzy główne Widget Tree z MaterialApp jako korzeniem.
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(),
);
}
}
W tym przykładzie MaterialApp konfiguruje podstawowy motyw (jasny i ciemny), tytuł i główny ekran. Parametr title jest używany do tytułu okna (na desktopie) i dla accessibility. Parametry theme i darkTheme określają wygląd aplikacji w różnych trybach.
MaterialApp przyjmuje ponad 30 parametrów, które dzielą się na kategorie: ustawienia Material Design, routing, motywacja, lokalizacja, zachowanie przy błędach i ustawienia dla konkretnych platform. Znajomość kluczowych parametrów pozwala elastycznie skonfigurować aplikację bez pisania dodatkowego kodu.
Parametr title ustawia nazwę aplikacji dla tytułu okna i accessibility. color określa kolor aplikacji dla przełącznika zadań na Androidzie. debugShowCheckedModeBanner ukrywa baner trybu debugowania w wydaniu produkcyjnym. showPerformanceOverlay włącza nakładkę z informacjami o wydajności. supportDarkTheme wskazuje, czy aplikacja obsługuje ciemny motyw.
MaterialApp udostępnia parametry do konfiguracji zachowania na różnych platformach: restorationScopeId do zapisywania stanu aplikacji przy restarcie na Androidzie, scrollBehavior do konfiguracji zachowania przewijania na różnych systemach operacyjnych, useMaterial3 do włączenia Material 3 (Material You). Material 3 dodaje dynamiczne kolory, nowe komponenty i zaktualizowane style.
| Parametr | Typ | Przeznaczenie |
|---|---|---|
| title | String | Tytuł okna aplikacji |
| theme | ThemeData | Jasny motyw aplikacji |
| darkTheme | ThemeData | Ciemny motyw aplikacji |
| home | Widget | Główny ekran aplikacji |
| routes | Map<String, WidgetBuilder> | Mapa nazwanych tras |
| locale | Locale | Wymuszona lokalizacja aplikacji |
Motywacja — jeden z głównych parametrów MaterialApp. Parametr theme przyjmuje obiekt ThemeData, który określa paletę kolorów, typografię, kształty komponentów i ikonografię dla jasnego motywu. Parametr darkTheme — analogiczna konfiguracja dla ciemnego motywu. Flutter automatycznie przełącza motyw w zależności od ustawień systemowych urządzenia.
ThemeData zawiera primarySwatch (kolor główny), colorScheme (rozszerzony schemat kolorów Material 3), brightness (jasny lub ciemny), fontFamily (domyślna czcionka), textTheme (style tekstu), cardTheme, appBarTheme, buttonTheme i dziesiątki innych parametrów do konfiguracji konkretnych komponentów. Używaj colorScheme dla Material 3 i primarySwatch dla Material 2.
Material 3 (Material You) obsługuje dynamiczne kolory, które są pobierane z tapety urządzenia na Androidzie 12+. Aby włączyć, ustaw useMaterial3: true i używaj colorScheme.fromSeed lub colorScheme.fromImageProvider. Dynamiczne kolory automatycznie generują harmonijną paletę z 5 tonów: primary, secondary, tertiary, neutral i neutralVariant.
Każdy widżet może uzyskać dostęp do bieżącego motywu przez Theme.of(context). Theme.of zwraca ThemeData, z którego można pobrać colors, textTheme i inne parametry. Aby subskrybować zmiany motywu (np. przy przełączaniu między jasnym a ciemnym), używaj kontekstu wewnątrz metody build — Flutter automatycznie przebuduje widżet przy zmianie motywu.
Container(
color: Theme.of(context).colorScheme.primary,
child: Text(
"Przykładowy tekst z motywem",
style: Theme.of(context).textTheme.headlineMedium,
),
)
W tym przykładzie Theme.of(context) pobiera bieżący motyw z najbliższego MaterialApp. Kolor tła i styl tekstu automatycznie odpowiadają bieżącemu motywowi (jasnemu lub ciemnemu). Przy przełączaniu motywu Container i Text przebudują się z nowymi wartościami z zaktualizowanego ThemeData.
MaterialApp integruje Navigator — nawigator stosowy, który zarządza przejściami między ekranami. Parametry initialRoute, routes i onGenerateRoute określają, jak Flutter obsługuje nawigację. Navigator.push i Navigator.pushReplacement pozwalają programowo przełączać ekrany, a Navigator.pop — wracać do poprzedniego.
Parametr routes przyjmuje Map
onGenerateRoute — to funkcja wywoływana, gdy trasa nie zostanie znaleziona w routes. Przyjmuje RouteSettings i zwraca MaterialPageRoute. To podejście jest przydatne do dynamicznej nawigacji, gdy trasy zależą od danych (np. /user/42). onGenerateRoute analizuje nazwę trasy, wyodrębnia parametry i tworzy odpowiedni ekran.
Do obsługi głębokich linków (deep links) używaj parametrów onGenerateInitialRoute i onGenerateRoute razem. Głębokie linki pozwalają otwierać określony ekran aplikacji przez URL (np. https://example.com/promo). Flutter obsługuje głębokie linki na Androidzie (przez intent filters) i iOS (przez universal links) i przekazuje ścieżkę do 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;
},
)
W tym przykładzie onGenerateRoute obsługuje dynamiczne trasy w formacie /user/42. Jeśli trasa nie zostanie znaleziona w statycznej routes i nie pasuje do dynamicznego wzorca, Flutter wyświetla stronę błędu, którą można skonfigurować przez onUnknownRoute.
MaterialApp zapewnia wbudowaną obsługę lokalizacji przez parametry localizationsDelegates i supportedLocales. LocalizationsDelegates ładują zlokalizowane ciągi znaków, a supportedLocales określa, które języki obsługuje aplikacja. Flutter automatycznie wykrywa język urządzenia i ładuje odpowiednie zlokalizowane zasoby.
Parametr supportedLocales przyjmuje listę Locale obsługiwanych przez aplikację: [const Locale('en'), const Locale('ru'), const Locale('de')]. localizationsDelegates — lista delegatów ładujących zlokalizowane ciągi znaków. Dla Material Design dodaj GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate i GlobalCupertinoLocalizations.delegate.
Do lokalizacji własnych ciągów używaj klasy AppLocalizations utworzonej przez flutter_localizations lub pakiet intl. AppLocalizations udostępnia statyczne metody dostępu do zlokalizowanych ciągów: AppLocalizations.of(context)!.helloMessage. MaterialApp automatycznie przekazuje Localizations do Widget Tree, czyniąc je dostępnymi przez kontekst.
Flutter udostępnia trzy główne widżety dla różnych platform: MaterialApp (Material Design dla Androida i sieci), CupertinoApp (styl iOS) i WidgetsApp (podstawowy widżet bez stylizacji). Wybór głównego widżetu określa wygląd całej aplikacji i dostępność komponentów platformy.
MaterialApp nadaje się dla większości aplikacji dzięki obsłudze Material Design, który dobrze wygląda na Androidzie, w sieci i na desktopie. Material Design zapewnia bogatą bibliotekę komponentów: Scaffold, AppBar, BottomNavigationBar, Drawer, SnackBar, Dialog i wiele innych. MaterialApp obsługuje również Material 3 z dynamicznymi kolorami.
CupertinoApp używa Cupertino Design zgodnego z Human Interface Guidelines od Apple. Udostępnia CupertinoPageScaffold, CupertinoNavigationBar, CupertinoTabBar i inne komponenty w stylu iOS. Używaj CupertinoApp dla aplikacji iOS lub aplikacji stosujących styl Apple na wszystkich platformach.
WidgetsApp — to podstawowy widżet główny bez stylizacji. Dodaje Navigator, MediaQuery i Localizations, ale nie udostępnia motywów ani komponentów Material/Cupertino. WidgetsApp nadaje się dla niestandardowych systemów projektowych, gier lub aplikacji z własną stylizacją, gdzie Material lub Cupertino jest zbędny.
| Główny widżet | System projektowy | Kiedy używać |
|---|---|---|
| MaterialApp | Material Design (Google) | Android, sieć, desktop, aplikacje wieloplatformowe |
| CupertinoApp | Cupertino (Apple HIG) | Aplikacje iOS, styl Apple na wszystkich platformach |
| WidgetsApp | Bez stylizacji | Niestandardowy design, gry, własne systemy projektowe |
Często zadawane pytania
Nie jest obowiązkowy — można użyć CupertinoApp dla stylu iOS lub WidgetsApp dla niestandardowego designu. MaterialApp jest obowiązkowy, jeśli używasz widżetów Material: Scaffold, AppBar, FloatingActionButton i innych.
Użyj parametrów theme (jasny motyw) i darkTheme (ciemny motyw). Flutter automatycznie przełącza motyw w zależności od ustawień systemowych. Do wymuszonego przełączania użyj WidgetsBinding.instance.platformDispatcher.platformBrightness.
Tak, domyślnie useMaterial3 ma wartość false i MaterialApp używa Material 2. Aby włączyć Material 3, ustaw useMaterial3: true i używaj colorScheme z ColorScheme.fromSeed.
Użyj parametru onUnknownRoute, który przyjmuje RouteSettings i zwraca MaterialPageRoute. Jeśli ani routes, ani onGenerateRoute nie obsłużyły trasy, wywoływany jest onUnknownRoute — zwróć w nim stronę z komunikatem błędu.
Jeśli parametr home nie jest podany i nie ma routes, Flutter wyrzuca wyjątek przy uruchomieniu. Należy podać co najmniej jeden z parametrów: home, routes z trasą '/' lub initialRoute.
Podsumowanie
Opracujemy aplikację mobilną pod klucz
IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.
Przeczytaj również