BuildContext — Flutter-də konkret vidjetin elementlər ağacındakı mövqeyini təmsil edən və onun mühitinə girişi təmin edən fundamental obyektdir. Rəsmi Flutter sənədlərinə görə (Flutter.dev, 2026), BuildContext vidjet və freymvork arasında körpüdür: onun vasitəsilə vidjet tema (Theme), media sorğuları (MediaQuery), lokallaşdırma (Localizations) və InheritedWidget-dən məlumatlar alır. Hər vidjetin build metoduna birinci arqument kimi ötürülən öz BuildContext-i var.
Əsas məqamlar
BuildContext — Element sinfi tərəfindən həyata keçirilən, vidjetə UI iyerarxiyasındakı yeri haqqında məlumat verən interfeysdir. Hər BuildContext nümunəsi ağacdakı konkret mövqe üçün unikaldır və başqa yerə köçürülə bilməz. Vidjet valideynini dəyişirsə (məsələn, başqa konteynerə köçürülürsə), yeni BuildContext alır.
BuildContext-in əsas təyinatı InheritedWidget-ə girişdir. Kontekst vasitəsilə vidjet ağacda yuxarı qalxaraq ən yaxın Theme, MediaQuery, Navigator və ya Directionality nümunəsini tapır. Bu mexanizm Flutter-də bütün tema, naviqasiya və adaptiv tərtibat sisteminin əsasını təşkil edir. BuildContext olmadan heç bir vidjet bu məlumatları əldə edə bilməz.
Flutter memarlıq sənədlərinə görə (Google, 2026), BuildContext həmçinin vidjetlə əlaqəli RenderObject obyektini axtarmaq, ölçüləri ölçmək və yerləşdirmək üçün istifadə olunur. findRenderObject() və size kimi metodlar məhz kontekst vasitəsilə əlçatandır. Kontekst həmçinin Localizations.of(context) vasitəsilə lokallaşdırmaya girişi təmin edir.
Vacib memarlıq anlayışı: BuildContext Widget deyil, Element-in həyata keçirdiyi interfeysdir. Element Widget (konfiqurasiya) ilə RenderObject (real göstərim) arasında „yapışqan” rolunu oynayır. Sənədlərdə „vidjet konteksti” deyildikdə, həmin vidjeti idarə edən element nəzərdə tutulur. build metodu məhz belə bir kontekst alır — yaradılan vidjetin konteksti, qaytarılan uşaq vidjetlərin deyil.
BuildContext-in iş mexanizmi elementlər ağacını aşağıdan yuxarıya doğru gəzməyə əsaslanır. Vidjet Theme.of(context) çağırdıqda, kontekst cari elementdən başlayaraq kökə doğru hərəkət edir və hər elementi Theme tipli InheritedWidget üçün yoxlayır. Tapılan ilk InheritedWidget qaytarılır — bu, vidjetin temanı ən yaxın təyinatdan almasını təmin edir.
Hər BuildContext valideyn kontekstinə (parent) və uşaq kontekstlərə istinad saxlayır. Bu, ağacda həm yuxarı (valideynlərə), həm də aşağı (nəsillərə) hərəkət etməyə imkan verən ikitərəfli əlaqədir. Flutter-də InheritedWidget axtarışı üçün yalnız yuxarı hərəkət istifadə olunur — vidjet məlumatları yalnız əcdadlardan ala bilər, nəsillərdən yox. Bu, fundamental memarlıq məhdudiyyətidir.
Flutter mənbə koduna görə (Flutter SDK, 2026), BuildContext aşağıdakı metodları ehtiva edir: visitAncestorElements, visitChildElements, findAncestorWidgetOfExactType, dependOnInheritedWidgetOfExactType və getRenderObject. Son ikisi ən çox istifadə olunur: dependOnInheritedWidgetOfExactType nəinki InheritedWidget tapır, həm də onun dəyişikliklərinə abunə olur (vidjet InheritedWidget dəyişdikdə yenidən qurulacaq).
dependOnInheritedWidgetOfExactType — reaktivliyi təmin edən BuildContext-in əsas metodudur. Vidjet Theme.of(context) çağırdıqda, o, sadəcə temanı almır — onun dəyişikliklərinə abunə olur. Theme dəyişirsə (məsələn, qaranlıq/işıqlı temanın dəyişdirilməsi zamanı), bütün abunə olan vidjetlər avtomatik yenidən qurulur. Bu, Flutter-də reaktivlik mexanizmidir.
BuildContext interfeys, Element isə onun həyata keçirilməsidir. Flutter kodunda siz həmişə BuildContext interfeysi vasitəsilə işləyirsiniz, elementin konkret tipini bilmədən (StatelessElement, StatefulElement, ProxyElement və s.). Bu qəsdən edilib: tərtibatçı elementin həyata keçirilməsinin detallarını bilməməlidir — mühitə giriş üçün interfeys kifayətdir.
Müxtəlif element növləri BuildContext-i fərqli həyata keçirir: StatelessElement sadəcə build çağırışlarını ötürür, StatefulElement State-i idarə edir, InheritedElement isə dependOnInheritedWidgetOfExactType vasitəsilə abunəlikləri izləyir. Lakin tərtibatçı baxımından hamısı vahid API ilə BuildContext-dir.
| Aspekt | BuildContext | Element |
|---|---|---|
| Tip | İnterfeys (abstract class) | Həyata keçirmə sinfi |
| İstifadə | Tərtibatçı tərəfindən build-də | Flutter-in daxili mexanizmi |
| Axtarış metodları | of(), findAncestor...() | mount, update, unmount |
| Açıqlıq | İctimai API | package-internal |
| Vidjetlə əlaqə | widget sahəsi vasitəsilə | Widget və state-ə sahibdir |
Tema və media sorğularına giriş üçün BuildContext-in əsas istifadəsi:
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,
),
);
}
}
BuildContext vasitəsilə naviqasiya nümunəsi. Navigator.of(context) kontekstdən istifadə edərək ağacda yuxarı ən yaxın Navigator-u axtarır:
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'),
);
}
}
BuildContext vasitəsilə vidjet ölçüsünün tapılması nümunəsi. findRenderObject() metodu RenderObject qaytarır, ondan ölçü əldə etmək olar:
void _printSize(BuildContext context) {
final renderBox = context.findRenderObject() as RenderBox?;
if (renderBox != null) {
print('Widget size: ${renderBox.size}');
}
}
Vacib: findRenderObject() vidjet hələ quraşdırılmayıbsa və ya artıq sökülübsə, null qaytarır. İstifadədən əvvəl həmişə nəticəni null üçün yoxlayın. Bu metodun build daxilində qurma tamamlanmazdan əvvəl çağırılması da null qaytara bilər.
InheritedWidget — məlumatları BuildContext vasitəsilə ağacda aşağı səmərəli şəkildə yayan xüsusi vidjetdir. Uşaq vidjet MyInheritedWidget.of(context) çağırdıqda, BuildContext ağacda qalxır, müvafiq tipli ən yaxın InheritedWidget-i tapır və onun məlumatlarını qaytarır. Bununla kontekst dəyişikliklərə abunə olur: InheritedWidget dəyişərsə, bütün abunə olan vidjetlər avtomatik yenidən qurulur.
BuildContext + InheritedWidget birləşməsi qlobal dəyişənləri və prop-drilling-i (məlumatların konstruktorlar zənciri vasitəsilə ötürülməsini) əvəz edir. Temanı 10 səviyyəli vidjetlər vasitəsilə ötürmək əvəzinə, hər vidjet onu birbaşa Theme.of(context) vasitəsilə əldə edə bilər. Bu, kodu daha təmiz edir və ötürülən parametrlərin sayını azaldır.
Flutter Team-ə görə (Google, aprel 2026), InheritedWidget o qədər effektiv mexanizmdir ki, onun əsasında bütün rəsmi vəziyyətin idarə edilməsi həlləri qurulub: Provider InheritedWidget-i bürüyür, Riverpod onu təbəqələrdən biri kimi istifadə edir, Flutter SDK-nın özü (Theme, MediaQuery, Navigator, Localizations) tamamilə bu memarlığa əsaslanır.
Öz InheritedWidget-ınızı yaratmaq xarici asılılıqlar olmadan məlumatları yaymağa imkan verir. Sinif InheritedWidget-i genişləndirir və of(BuildContext context) statik metodunu təqdim edir. Bu, sadə ssenarilər üçün Provider-ə minimalist alternativdir:
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;
}
}
İndi ağacda aşağıdakı hər vidjet konfiqurasiyaya giriş əldə edə bilər: final config = AppConfig.of(context);. Konfiqurasiya dəyişərsə, bütün abunə olan vidjetlər avtomatik yenidən qurulacaq.
Birinci tipik səhv — BuildContext-i dispose-dan sonra saxlamaq və ya mounted yoxlanışı olmadan asinxron geri çağırışda istifadə etmək. BuildContext elementə bağlıdır və element məhv edilə bilər (vidjet ağacdan silindikdə). Elementin məhvindən sonra kontekstdən istifadə istisnaya səbəb olur. Həll — context.mounted (Flutter-in yeni versiyalarında mövcuddur) istifadə etmək və ya State-də mounted yoxlamaq.
İkinci səhv — initState-də Theme.of(context) çağırmaq. initState mərhələsində kontekst hələ ağacda tam quraşdırılmayıb. initState-də InheritedWidget axtarışı null qaytara və ya istisna ata bilər. Bütün of(context) çağırışları build və ya didChangeDependencies-də yerinə yetirilməlidir, burada kontekst ağacda olması təmin edilir.
Üçüncü səhv — bir vidjetin BuildContext-indən başqa vidjeti manipulyasiya etmək üçün istifadə etmək. BuildContext „valideyn-uşaq” iyerarxiyasından kənarda vidjetlərarası qarşılıqlı əlaqə üçün nəzərdə tutulmayıb. Başqa vidjetin vəziyyətini idarə etmək lazımdırsa — geri çağırışlar, kontrollerlər və ya vəziyyətin idarə edilməsi alətlərindən istifadə edin.
Dördüncü səhv — BuildContext-i vidjetin dispose-unu ötüb keçən asinxron funksiyaya ötürmək. Tipik ssenari: Navigator.of(context) dəyişəndə saxlanılır və istifadəçi ekrandan çıxdıqdan sonra istifadə olunur. Həll — konteksti statik və ya uzunömürlü obyektlərdə saxlamaq olmaz.
BuildContext ilə asinxron əməliyyatlarda iş üçün təhlükəsizlik nümunəsi: kontekstdən istifadə etməzdən əvvəl həmişə mounted yoxlayın və konteksti vidjeti ötüb keçə bilən qapanmalarda saxlamayın:
Future<void> _safeNavigation(BuildContext context) async {
await Future.delayed(const Duration(seconds: 2));
if (!context.mounted) return;
Navigator.of(context).push(MaterialPageRoute(...));
}
BuildContext ilə iş onun həyat dövrünü və məhdudiyyətlərini anlamaq tələb edir. Birinci qayda: kontekstdən yalnız onu parametr kimi qəbul edən metodlar daxilində istifadə edin (build, didChangeDependencies). Konteksti sinif sahələrində və ya statik dəyişənlərdə saxlamayın — bu, demək olar ki, həmişə səhvlərə gətirib çıxarır.
İkinci qayda: InheritedWidget-dən məlumatlara giriş üçün build əvəzinə didChangeDependencies-ə üstünlük verin. Məlumatlar yalnız inisializasiya üçün lazımdırsa, render üçün deyilsə, didChangeDependencies düzgün yerdir. Bu, inisializasiya məntiqini UI qurulmasından ayırmağa və hər yeniləmədə təkrar çağırışların qarşısını almağa imkan verir.
Üçüncü qayda: asinxron əməliyyatlarla işləyərkən kontekstdən asılı olmayan geri çağırışlardan istifadə edin və ya mounted yoxlayın. Asinxron əməliyyat naviqasiya və ya temaya giriş tələb edirsə, bu məlumatları əvvəlcədən (sinxron build və ya initState kontekstində) əldə edin və kontekstdə deyil, yerli dəyişənlərdə saxlayın.
Tez-tez verilən suallar
BuildContext — vidjetin elementlər ağacındakı mövqeyini təmsil edən interfeysdir. Onun vasitəsilə vidjet mühitə giriş əldə edir: tema, media sorğuları, naviqator və InheritedWidget-dən məlumatlar. Hər vidjetin öz unikal konteksti var.
BuildContext ağacı cari elementdən kökə qədər gəzərək, tələb olunan tipli ən yaxın InheritedWidget-i tapır. dependOnInheritedWidgetOfExactType metodu nəinki məlumatları tapır, həm də vidjeti onların dəyişikliklərinə abunə edir — InheritedWidget yeniləndikdə vidjet avtomatik yenidən qurulur.
BuildContext ağacdakı elementə bağlıdır və element məhv edilə bilər (vidjet silindikdə). Saxlanılmış kontekstdən vidjet silindikdən sonra istifadə istisnaya səbəb olur. Kontekst asinxron geri çağırışda lazımdırsa — istifadədən əvvəl mounted yoxlayın.
BuildContext interfeys, Element isə həyata keçirmədir. Tərtibatçı BuildContext vasitəsilə işləyir, elementin konkret tipini bilmədən. Element — Widget-i RenderObject ilə birləşdirən və həyat dövrünü idarə edən Flutter-in daxili mexanizmidir.
Başqa vidjetin kontekstinə birbaşa giriş yoxdur. Valideyn konteksti üçün State üçün context.findAncestorStateOfType və ya açar (GlobalKey) istifadə edin. Uşaq üçün — geri çağırış ötürün. BuildContext iyerarxiyadan kənarda vidjetlərarası giriş üçün nəzərdə tutulmayıb.
Xülasə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun