BuildContext — bu nədir, əsas anlayışlar və iş prinsipi

Müəllif: IT Sectr Dərc olunub: 2026-07-01 Oxuma vaxtı: 9 dəq

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 — vidjetin elementlər ağacındakı mövqeyini təmsil edən və onun iyerarxik mühitinə girişi təmin edən obyektdir
  • InheritedWidget — BuildContext vasitəsilə əldə edilən, məlumatları ağacda aşağı ötürmək üçün əsas mexanizmdir
  • of() metodu — BuildContext-dən istifadə edərək ağacda yuxarı ən yaxın InheritedWidget-i axtaran statik metod (Theme.of, MediaQuery.of)
  • Kontekst və həyat dövrü — BuildContext vidjetin yeri dəyişdikdə dəyişir; dispose-dan sonra kontekstə istinad saxlanıla bilməz
  • Səhvlər — BuildContext-in öz ağacından kənarda və ya dispose-dan sonra istifadəsi istisnalara səbəb olur (isti yenidən yükləmələr, asinxron geri çağırışlar)

BuildContext nədir?

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()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.

BuildContext elementdir, vidjet deyil

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 necə işləyir?

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, dependOnInheritedWidgetOfExactTypegetRenderObject. 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).

Kontekst vasitəsilə abunəlik

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 vs Element

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.

AspektBuildContextElement
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 APIpackage-internal
Vidjetlə əlaqəwidget sahəsi vasitəsiləWidget və state-ə sahibdir

Dart dilində kod nümunələri

Tema və media sorğularına giriş üçün BuildContext-in əsas istifadəsi:

dart
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:

dart
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:

dart
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 və BuildContext

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

Ö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:

dart
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.

Tipik səhvlər

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.

Asinxron əməliyyatlarda kontekst

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:

dart
Future<void> _safeNavigation(BuildContext context) async {
  await Future.delayed(const Duration(seconds: 2));
  if (!context.mounted) return;
  Navigator.of(context).push(MaterialPageRoute(...));
}

Ən yaxşı təcrübələr

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.

Kontekst nə vaxt lazımdır və nə vaxt yox

  • Lazımdır: Theme, MediaQuery, Navigator, Localizations, ScaffoldMessenger-ə giriş
  • Lazımdır: ölçüləri ölçmək üçün RenderObject axtarışı
  • Lazımdır: SnackBar, BottomSheet, Dialog yaratmaq
  • Lazım deyil: biznes məntiqi metodlarının çağırılması, HTTP sorğuları, verilənlər bazası ilə iş
  • Lazım deyil: build-dən kənarda vidjetlərin qurulması (fabriklərdə, konstruktorlarda)

Tez-tez verilən suallar

Flutter-də BuildContext nədir?

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 necə işləyir?

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.

Niyə BuildContext sinif sahələrində saxlanıla bilməz?

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 və Element arasında fərq nədir?

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 BuildContext-ni əldə etmək olarmı?

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ə

  • BuildContext — vidjetin ağacdakı mövqeyini təmsil edən və InheritedWidget vasitəsilə iyerarxik mühitə girişi təmin edən fundamental Flutter obyektidir
  • Axtarış mexanizmi — BuildContext ağacı aşağıdan yuxarı gəzərək, tələb olunan tipli ən yaxın InheritedWidget-i tapır və onun dəyişikliklərinə abunə olur
  • Əsas istifadə — temalara, adaptivliyə və naviqasiyaya giriş üçün Theme.of(context), MediaQuery.of(context), Navigator.of(context)
  • BuildContext vs Element — BuildContext ictimai interfeys, Element — özəl həyata keçirmədir. Tərtibatçı həmişə BuildContext vasitəsilə işləyir
  • Həyat dövrü — BuildContext müvafiq element yaşadıqca yaşayır; dispose-dan sonra kontekstdən istifadə edilməməlidir
  • Səhvlər — konteksti uzunömürlü obyektlərdə saxlamaq, initState-də istifadə, dispose-dan sonra istifadə — tez-tez rast gəlinən səhv mənbələridir
  • Qayda — BuildContext-dən yalnız build/didChangeDependencies daxilində istifadə edin, onu saxlamayın, asinxron ssenarilərdə mounted yoxlayın

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.

Layihəni müzakirə et

Həm də oxuyun