BuildContext — egy alapvető Flutter-objektum, amely egy adott widget helyzetét reprezentálja az elemfában, és hozzáférést biztosít a környezetéhez. A hivatalos Flutter dokumentáció (Flutter.dev, 2026) szerint a BuildContext híd a widget és a keretrendszer között: rajta keresztül a widget megkapja a témát (Theme), a média lekérdezéseket (MediaQuery), a lokalizációt (Localizations) és az InheritedWidget adatait. Minden widget rendelkezik saját BuildContext-tel, amely első argumentumként kerül átadásra a build metódusnak.
Főbb pontok
BuildContext — egy interfész, amelyet az Element osztály valósít meg, és amely információt nyújt a widgetnek az UI-hierarchiában elfoglalt helyéről. Minden BuildContext-példány egyedi egy adott pozícióra a fában, és nem helyezhető át más helyre. Ha a widget megváltoztatja a szülőjét (például áthelyezésre kerül egy másik konténerbe), új BuildContext-et kap.
A BuildContext fő célja az InheritedWidget elérése. A kontextuson keresztül a widget megtalálja a legközelebbi Theme, MediaQuery, Navigator vagy Directionality példányt, felfelé haladva a fában. Ez a mechanizmus képezi az egész téma-, navigációs és adaptív elrendezési rendszer alapját a Flutterben. BuildContext nélkül egyetlen widget sem képes ezeket az adatokat megszerezni.
A Flutter architekturális dokumentációja (Google, 2026) szerint a BuildContext a widgethez tartozó RenderObject-objektum megtalálására is szolgál, a méretek mérésére és pozicionálásra. Az olyan metódusok, mint a findRenderObject() és a size, éppen a kontextuson keresztül érhetők el. A kontextus a Localizations.of(context) segítségével hozzáférést biztosít a lokalizációhoz is.
Fontos architekturális megértés: a BuildContext egy interfész, amelyet Element valósít meg, nem Widget. Az Element a „ragasztó” a Widget (konfiguráció) és a RenderObject (tényleges megjelenítés) között. Amikor a dokumentáció „widget kontextusát” említi, az arra az elemre utal, amely azt a widgetet kezeli. A build metódus pontosan ilyen kontextust kap — a létrehozott widget kontextusát, nem a visszaadott gyermek widgetekét.
A BuildContext működési mechanizmusa az elemfa alulról felfelé történő bejárásán alapul. Amikor a widget meghívja a Theme.of(context)-et, a kontextus elindítja a keresést az aktuális elemtől, és felfelé halad a gyökér felé, ellenőrizve minden elemet InheritedWidget jelenlétére Theme típussal. Az első megtalált InheritedWidget visszaadásra kerül — ez garantálja, hogy a widget a legközelebbi definícióból kapja a témát.
Minden BuildContext tárol egy hivatkozást a szülő kontextusra (parent) és a gyermek kontextusokra. Ez egy kétirányú kapcsolat, amely lehetővé teszi a mozgást a fában felfelé (szülőkhöz) és lefelé (leszármazottakhoz) egyaránt. A Flutterben az InheritedWidget kereséséhez csak felfelé irányuló mozgást használunk — a widget csak az ősöktől kaphat adatokat, nem a leszármazottaktól. Ez egy alapvető architekturális korlátozás.
A Flutter forráskódja (Flutter SDK, 2026) szerint a BuildContext a következő metódusokat tartalmazza: visitAncestorElements, visitChildElements, findAncestorWidgetOfExactType, dependOnInheritedWidgetOfExactType és getRenderObject. Az utóbbi kettő a leggyakrabban használt: a dependOnInheritedWidgetOfExactType nemcsak megtalálja az InheritedWidget-ot, hanem fel is iratkozik a változásaira (a widget újraépül, amikor az InheritedWidget megváltozik).
dependOnInheritedWidgetOfExactType — a BuildContext kulcsmetódusa, amely biztosítja a reaktivitást. Amikor a widget meghívja a Theme.of(context)-et, nemcsak megkapja a témát — feliratkozik a változásaira. Ha a Theme megváltozik (például a sötét/világos téma váltásakor), az összes feliratkozott widget automatikusan újraépül. Ez a reaktivitás mechanizmusa a Flutterben.
A BuildContext egy interfész, az Element pedig — annak implementációja. A Flutter kódban mindig a BuildContext interfészen keresztül dolgozik, anélkül, hogy ismerné az elem konkrét típusát (StatelessElement, StatefulElement, ProxyElement stb.). Ez szándékos: a fejlesztőnek nem kell ismernie az elem implementációs részleteit — az interfész elegendő a környezet eléréséhez.
A különböző elemtípusok eltérően valósítják meg a BuildContext-et: a StatelessElement egyszerűen továbbítja a build hívásokat, a StatefulElement kezeli a State-et, az InheritedElement pedig a dependOnInheritedWidgetOfExactType segítségével követi a feliratkozásokat. A fejlesztő szemszögéből azonban mindegyik BuildContext egységes API-val.
| Szempont | BuildContext | Element |
|---|---|---|
| Típus | Interfész (abstract class) | Implementációs osztály |
| Használat | Fejlesztő által a build-ben | Flutter belső mechanizmusa |
| Keresési metódusok | of(), findAncestor...() | mount, update, unmount |
| Nyilvánosság | Nyilvános API | package-internal |
| Kapcsolat a widget-tel | A widget mezőn keresztül | Birtokolja a widget-et és state-et |
A BuildContext alapvető használata a téma és média lekérdezések eléréséhez:
class ThemedText extends StatelessWidget {
const ThemedText({super.key});
@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final media = MediaQuery.of(context);
return Container(
padding: EdgeInsets.all(media.size.width * 0.02),
child: Text(
'Styled Text',
style: theme.textTheme.headlineMedium,
),
);
}
}
Példa navigációval a BuildContext-en keresztül. A Navigator.of(context) a kontextust használja a legközelebbi Navigator megtalálásához felfelé a fában:
class _NavigateButtonState extends State<NavigateButton> {
void _navigate() {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => const DetailsScreen(),
),
);
}
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: _navigate,
child: const Text('Go to Details'),
);
}
}
Példa a widget méretének megtalálására a BuildContext-en keresztül. A findRenderObject() metódus egy RenderObject-ot ad vissza, amelyből a méret kinyerhető:
void _printSize(BuildContext context) {
final renderBox = context.findRenderObject() as RenderBox?;
if (renderBox != null) {
print('Widget size: ${renderBox.size}');
}
}
Fontos: a findRenderObject() null-t ad vissza, ha a widget még nincs csatlakoztatva vagy már le lett választva. Mindig ellenőrizze az eredményt null-ra használat előtt. A metódus meghívása a build-en belül az építés befejezése előtt szintén null-t adhat vissza.
InheritedWidget — egy speciális widget, amely hatékonyan terjeszti az adatokat lefelé a fában a BuildContext-en keresztül. Amikor a gyermek widget meghívja a MyInheritedWidget.of(context)-et, a BuildContext felfelé halad a fában, megtalálja a megfelelő típusú legközelebbi InheritedWidget-ot, és visszaadja annak adatait. Eközben a kontextus feliratkozik a változásokra: ha az InheritedWidget megváltozik, az összes feliratkozott widget automatikusan újraépül.
A BuildContext + InheritedWidget kombináció helyettesíti a globális változókat és a prop-drilling-et (adatok továbbítása konstruktorok láncán keresztül). Ahelyett, hogy a témát 10 szintnyi widgeten keresztül adná át, minden widget közvetlenül megszerezheti azt a Theme.of(context) segítségével. Ez tisztábbá teszi a kódot és csökkenti az átadott paraméterek számát.
A Flutter Team (Google, 2026. április) szerint az InheritedWidget olyan hatékony mechanizmus, hogy az összes hivatalos állapotkezelési megoldás erre épül: a Provider beburkolja az InheritedWidget-ot, a Riverpod rétegek egyikeként használja, és maga a Flutter SDK (Theme, MediaQuery, Navigator, Localizations) is teljes mértékben ezen az architektúrán alapul.
Saját InheritedWidget létrehozása lehetővé teszi az adatok terjesztését külső függőségek nélkül. Az osztály kiterjeszti az InheritedWidget-ot, és biztosít egy of(BuildContext context) statikus metódust. Ez egy minimalista alternatíva a Provider számára egyszerű forgatókönyvekben:
class AppConfig extends InheritedWidget {
final String apiUrl;
final bool useDarkMode;
const AppConfig({
super.key,
required this.apiUrl,
required this.useDarkMode,
required super.child,
});
static AppConfig of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<AppConfig>()!;
}
@override
bool updateShouldNotify(AppConfig oldWidget) {
return apiUrl != oldWidget.apiUrl || useDarkMode != oldWidget.useDarkMode;
}
}
Mostantól bármely widget lejjebb a fában hozzáférhet a konfigurációhoz: final config = AppConfig.of(context);. Ha a konfiguráció megváltozik, az összes feliratkozott widget automatikusan újraépül.
Az első tipikus hiba — a BuildContext tárolása dispose után vagy aszinkron visszahívásban történő használata a mounted ellenőrzése nélkül. A BuildContext az elemhez van kötve, és az elem megsemmisülhet (a widget eltávolításakor a fából). A kontextus használata az elem megsemmisülése után kivételhez vezet. Megoldás — használja a context.mounted-et (elérhető a Flutter újabb verzióiban), vagy ellenőrizze a mounted-et a State-ben.
A második hiba — a Theme.of(context) meghívása initState-ben. Az initState fázisban a kontextus még nincs teljesen csatlakoztatva a fában. Az InheritedWidget keresése initState-ben null-t adhat vissza, vagy kivételt dobhat. Az összes of(context) hívást a build-ben vagy a didChangeDependencies-ben kell végrehajtani, ahol a kontextus garantáltan a fában van.
A harmadik hiba — az egyik widget BuildContext-jének használata egy másik widget manipulálásához. A BuildContext nem a „szülő-gyermek” hierarchián kívüli widgetek közötti interakcióra szolgál. Ha egy másik widget állapotát kell kezelnie — használjon visszahívásokat, vezérlőket vagy állapotkezelő eszközöket.
A negyedik hiba — a BuildContext átadása egy olyan aszinkron függvénynek, amely túléli a widget dispose-át. Tipikus forgatókönyv: a Navigator.of(context) eltárolása egy változóban, majd használata miután a felhasználó elhagyta a képernyőt. Megoldás — ne tárolja a kontextust statikus vagy hosszú életű objektumokban.
Biztonsági minta a BuildContext-tel való munkához aszinkron műveletekben: mindig ellenőrizze a mounted-et a kontextus használata előtt, és ne tárolja a kontextust olyan closure-ökben, amelyek túlélhetik a widget-et:
Future<void> _safeNavigation(BuildContext context) async {
await Future.delayed(const Duration(seconds: 2));
if (!context.mounted) return;
Navigator.of(context).push(MaterialPageRoute(...));
}
A BuildContext-tel való munka megköveteli az életciklusának és korlátainak megértését. Első szabály: csak azokon a metódusokon belül használja a kontextust, amelyek paraméterként kapják azt (build, didChangeDependencies). Ne tárolja a kontextust osztálymezőkben vagy statikus változókban — ez szinte mindig hibákhoz vezet.
Második szabály: az InheritedWidget adatainak eléréséhez részesítse előnyben a didChangeDependencies-t a build-del szemben. Ha az adatok csak inicializáláshoz szükségesek, nem pedig megjelenítéshez, a didChangeDependencies a megfelelő hely. Ez lehetővé teszi az inicializálási logika elkülönítését az UI felépítésétől, és elkerüli az ismételt hívásokat minden frissítéskor.
Harmadik szabály: aszinkron műveletek esetén használjon olyan visszahívásokat, amelyek nem függnek a kontextustól, vagy ellenőrizze a mounted-et. Ha egy aszinkron művelet navigációt vagy témához való hozzáférést igényel, szerezze be ezeket az adatokat előre (a build vagy initState szinkron kontextusában), és tárolja lokális változókban, ne a kontextusban.
Gyakran ismételt kérdések
BuildContext — interfész, amely a widget pozícióját reprezentálja az elemfában. Rajta keresztül a widget hozzáfér a környezethez: témához, média lekérdezésekhez, navigátorhoz és InheritedWidget adataihoz. Minden widget rendelkezik saját egyedi kontextussal.
BuildContext bejárja a fát az aktuális elemtől felfelé a gyökér felé, megtalálva a kért típusú legközelebbi InheritedWidget-ot. A dependOnInheritedWidgetOfExactType metódus nemcsak megtalálja az adatokat, hanem fel is iratkoztatja a widget-et a változásaikra — az InheritedWidget frissítésekor a widget automatikusan újraépül.
A BuildContext kötődik a fában lévő elemhez, és az elem megsemmisülhet (a widget eltávolításakor). Az eltárolt kontextus használata a widget eltávolítása után kivételhez vezet. Ha a kontextus aszinkron visszahívásban szükséges — ellenőrizze a mounted-et használat előtt.
A BuildContext egy interfész, az Element — implementáció. A fejlesztő a BuildContext-en keresztül dolgozik, anélkül, hogy ismerné az elem konkrét típusát. Az Element — a Flutter belső mechanizmusa, amely összeköti a Widget-et a RenderObject-tal és kezeli az életciklust.
Nincs közvetlen hozzáférés egy másik widget kontextusához. A szülő kontextushoz használja a context.findAncestorStateOfType-et State-hez vagy kulcsokat (GlobalKey). A gyermek számára — adjon át egy visszahívást. A BuildContext nem a hierarchián kívüli widgetek közötti hozzáférésre szolgál.
Összefoglalás
Kulcsrakész mobilalkalmazást fejlesztünk
Az IT Sectr 2017 óta készít iOS és Android alkalmazásokat induló vállalkozásoknak és vállalkozásoknak. Tanácsot adunk, és a legjobb megoldást javasoljuk.
Olvassa el is