BuildContext, öğe ağacında belirli bir widget’ın konumunu temsil eden ve çevresine erişim sağlayan temel bir Flutter nesnesidir. Resmi Flutter belgelerine (Flutter.dev, 2026) göre BuildContext, widget ile framework arasında bir köprü görevi görür: bu sayede widget, temayı (Theme), medya sorgularını (MediaQuery), yerelleştirmeyi (Localizations) ve InheritedWidget’dan verileri alır. Her widget’ın, build yöntemine ilk argüman olarak iletilen kendi BuildContext’i vardır.
Önemli Noktalar
BuildContext, Element sınıfı tarafından uygulanan ve bir widget’a UI hiyerarşisindeki konumu hakkında bilgi sağlayan bir arayüzdür. Her BuildContext örneği, ağaçtaki belirli bir konum için benzersizdir ve başka bir yere taşınamaz. Bir widget ebeveynini değiştirirse (örneğin başka bir kapsayıcıya taşınırsa), yeni bir BuildContext alır.
BuildContext’in ana amacı InheritedWidget’a erişim sağlamaktır. Bağlam aracılığıyla bir widget, ağaçta yukarı doğru ilerleyerek en yakın Theme, MediaQuery, Navigator veya Directionality örneğini bulur. Bu mekanizma, Flutter’daki tema, navigasyon ve uyarlanabilir düzen sisteminin temelini oluşturur. BuildContext olmadan hiçbir widget bu verilere erişemez.
Flutter mimari belgelerine (Google, 2026) göre BuildContext, boyutları ölçmek ve konumlandırma için bir widget’la ilişkili RenderObject’u bulmak için de kullanılır. findRenderObject() ve size gibi yöntemler bağlam üzerinden kullanılabilir. Bağlam ayrıca Localizations.of(context) aracılığıyla yerelleştirmeye erişim sağlar.
Önemli bir mimari anlayış: BuildContext, Element tarafından uygulanan bir arayüzdür, Widget tarafından değil. Element, Widget (yapılandırma) ile RenderObject (gerçek görüntüleme) arasındaki “yapıştırıcıdır”. Belgeler “widget bağlamı” dediğinde, bu widget’ı yöneten öğeyi kasteder. build yöntemi tam olarak bu tür bir bağlam alır — oluşturulmakta olan widget’ın bağlamı, döndürdüğü alt widget’ların değil.
BuildContext mekanizması, öğe ağacını aşağıdan yukarıya doğru geçmeye dayanır. Bir widget Theme.of(context) çağırdığında, bağlam geçerli öğeden aramaya başlar ve köke doğru yukarı hareket ederek her öğeyi Theme türünde bir InheritedWidget için kontrol eder. Bulunan ilk InheritedWidget döndürülür — bu, widget’ın temayı en yakın tanımdan almasını garanti eder.
Her BuildContext, ebeveyn bağlama (parent) ve alt bağlamlara bir referans depolar. Bu, ağaçta hem yukarı (ebeveynlere) hem de aşağı (çocuklara) doğru gezinmeye izin veren çift yönlü bir bağlantıdır. Flutter’da InheritedWidget araması yalnızca yukarı doğru gezinmeyi kullanır — bir widget yalnızca atalarından veri alabilir, torunlarından alamaz. Bu temel bir mimari kısıtlamadır.
Flutter kaynak koduna (Flutter SDK, 2026) göre BuildContext şu yöntemleri içerir: visitAncestorElements, visitChildElements, findAncestorWidgetOfExactType, dependOnInheritedWidgetOfExactType ve getRenderObject. Son ikisi en çok kullanılanlardır: dependOnInheritedWidgetOfExactType yalnızca InheritedWidget’ı bulmakla kalmaz, aynı zamanda değişikliklerine abone olur (InheritedWidget değiştiğinde widget yeniden oluşturulur).
dependOnInheritedWidgetOfExactType, tepkiselliği sağlayan BuildContext’in anahtar yöntemidir. Bir widget Theme.of(context) çağırdığında, yalnızca temayı almakla kalmaz — aynı zamanda değişikliklerine abone olur. Theme değişirse (örneğin karanlık/aydınlık mod arasında geçiş yaparken), abone olan tüm widget’lar otomatik olarak yeniden oluşturulur. Flutter’daki tepkisellik mekanizması budur.
BuildContext bir arayüzdür, Element ise onun uygulamasıdır. Flutter kodunda, belirli öğe türünü (StatelessElement, StatefulElement, ProxyElement vb.) bilmeden her zaman BuildContext arayüzü üzerinden çalışırsın. Bu kasıtlıdır: geliştiricinin öğenin uygulama detaylarını bilmesi gerekmez — çevreye erişmek için arayüz yeterlidir.
Farklı öğe türleri BuildContext’i farklı şekillerde uygular: StatelessElement build çağrılarını basitçe iletir, StatefulElement State’i yönetir ve InheritedElement, dependOnInheritedWidgetOfExactType aracılığıyla abonelikleri takip eder. Ancak geliştirici açısından bakıldığında, hepsi birleşik bir API ile BuildContext’tir.
| Yön | BuildContext | Element |
|---|---|---|
| Tür | Arayüz (soyut sınıf) | Uygulama sınıfı |
| Kullanım | Geliştirici tarafından build’de | Flutter iç mekanizması |
| Arama yöntemleri | of(), findAncestor...() | mount, update, unmount |
| Kamuya açıklık | Kamuya açık API | Paket içi |
| Widget ilişkisi | widget alanı aracılığıyla | widget ve state’e sahiptir |
Temaya ve medya sorgularına erişmek için BuildContext’in temel kullanımı:
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(
'Stilize Edilmiş Metin',
style: theme.textTheme.headlineMedium,
),
);
}
}
BuildContext aracılığıyla navigasyon örneği. Navigator.of(context), ağaçta yukarı doğru en yakın Navigator’ı bulmak için bağlamı kullanı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('Detaylara Git'),
);
}
}
BuildContext aracılığıyla bir widget’ın boyutunu bulma örneği. findRenderObject() yöntemi, boyutun alınabileceği bir RenderObject döndürür:
void _printSize(BuildContext context) {
final renderBox = context.findRenderObject() as RenderBox?;
if (renderBox != null) {
print('Widget boyutu: ${renderBox.size}');
}
}
Önemli: findRenderObject(), widget henüz monte edilmemişse veya zaten demonte edilmişse null döndürür. Kullanmadan önce sonucu her zaman null için kontrol edin. Yapım tamamlanmadan önce build içinde bu yöntemi çağırmak da null döndürebilir.
InheritedWidget, BuildContext aracılığıyla ağaçta aşağıya doğru verileri verimli bir şekilde yayan özel bir widget’tır. Bir alt widget MyInheritedWidget.of(context) çağırdığında, BuildContext ağaçta yukarı doğru ilerler, eşleşen türdeki en yakın InheritedWidget’ı bulur ve verilerini döndürür. Aynı anda bağlam değişikliklere abone olur: InheritedWidget değişirse, abone olan tüm widget’lar otomatik olarak yeniden oluşturulur.
BuildContext + InheritedWidget kombinasyonu, global değişkenlerin ve prop drilling’in (yapıcı zinciri aracılığıyla veri iletme) yerini alır. 10 seviye widget üzerinden bir tema iletmek yerine, her widget doğrudan Theme.of(context) aracılığıyla erişebilir. Bu, kodu daha temiz hale getirir ve iletilen parametre sayısını azaltır.
Flutter Ekibi’ne (Google, Nisan 2026) göre InheritedWidget o kadar verimli bir mekanizmadır ki tüm resmi durum yönetimi çözümleri bunun üzerine inşa edilmiştir: Provider, InheritedWidget’ı sarar; Riverpod, onu katmanlarından biri olarak kullanır; ve Flutter SDK’nın kendisi (Theme, MediaQuery, Navigator, Localizations) tamamen bu mimariye dayanır.
Kendi InheritedWidget’ınızı oluşturmak, harici bağımlılıklar olmadan veri yaymanıza olanak tanır. Sınıf, InheritedWidget’ı genişletir ve statik bir of(BuildContext context) yöntemi sağlar. Bu, basit senaryolar için Provider’a minimal bir alternatiftir:
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;
}
}
Artık ağaçta daha aşağıdaki herhangi bir widget yapılandırmaya erişebilir: final config = AppConfig.of(context);. Yapılandırma değişirse, abone olan tüm widget’lar otomatik olarak yeniden oluşturulacaktır.
İlk yaygın hata, dispose’tan sonra BuildContext’i saklamak veya mounted kontrolü yapmadan async callback’te kullanmaktır. BuildContext bir öğeye bağlıdır ve öğe yok edilebilir (widget ağaçtan kaldırıldığında). Öğe yok edildikten sonra bağlamı kullanmak istisnaya yol açar. Çözüm, context.mounted (daha yeni Flutter sürümlerinde mevcut) kullanmak veya State‘te mounted‘ı kontrol etmektir.
İkinci hata, initState‘te Theme.of(context) çağırmaktır. initState aşamasında bağlam henüz ağaçta tamamen monte edilmemiştir. initState‘te InheritedWidget aramak null döndürebilir veya istisna fırlatabilir. Tüm of(context) çağrıları, bağlamın ağaçta olması garanti edilen build veya didChangeDependencies içinde yapılmalıdır.
Üçüncü hata, bir widget’ın BuildContext‘ini başka bir widget’ı manipüle etmek için kullanmaktır. BuildContext, ebeveyn-çocuk hiyerarşisi dışında widget’lar arası etkileşim için tasarlanmamıştır. Başka bir widget’ın durumunu yönetmeniz gerekiyorsa, callback, denetleyici veya durum yönetimi araçları kullanın.
Dördüncü hata, BuildContext‘i widget’ın dispose’undan daha uzun yaşayan bir async fonksiyona iletmektir. Tipik bir senaryo: Navigator.of(context) bir değişkende saklanır ve kullanıcı ekrandan ayrıldıktan sonra kullanılır. Çözüm, bağlamı statik veya uzun ömürlü nesnelerde saklamamaktır.
Async işlemlerde BuildContext ile çalışmak için bir güvenlik deseni: bağlamı kullanmadan önce her zaman mounted‘ı kontrol edin ve bağlamı, widget’tan daha uzun yaşayabilecek closure’larda saklamayın:
Future<void> _safeNavigation(BuildContext context) async {
await Future.delayed(const Duration(seconds: 2));
if (!context.mounted) return;
Navigator.of(context).push(MaterialPageRoute(...));
}
BuildContext ile çalışmak, yaşam döngüsünü ve sınırlamalarını anlamayı gerektirir. İlk kural: bağlamı yalnızca onu parametre olarak alan yöntemler içinde kullanın (build, didChangeDependencies). Bağlamı sınıf alanlarında veya statik değişkenlerde saklamayın — bu neredeyse her zaman hatalara yol açar.
İkinci kural: InheritedWidget’dan verilere erişmek için build yerine didChangeDependencies’i tercih edin. Veriler yalnızca başlatma için gerekliyse ve işleme için değilse, didChangeDependencies doğru yerdir. Bu, başlatma mantığını UI oluşumundan ayırmaya olanak tanır ve her güncellemede tekrarlanan çağrıları önler.
Üçüncü kural: async işlemlerle çalışırken, bağlama bağlı olmayan callback’ler kullanın veya mounted‘ı kontrol edin. Bir async işlem navigasyon veya temaya erişim gerektiriyorsa, bu verileri önceden (senkron bir build veya initState bağlamında) alın ve bağlamda değil, yerel değişkenlerde saklayın.
Sıkça Sorulan Sorular
BuildContext, öğe ağacında bir widget’ın konumunu temsil eden bir arayüzdür. Bu sayede widget, çevresine erişir: tema, medya sorguları, gezgin ve InheritedWidget’dan veriler. Her widget’ın kendine özgü bir bağlamı vardır.
BuildContext, geçerli öğeden köke doğru ağacı yukarı geçer ve istenen türdeki en yakın InheritedWidget’ı bulur. dependOnInheritedWidgetOfExactType yöntemi yalnızca verileri bulmakla kalmaz, aynı zamanda widget’ı değişikliklere abone eder — InheritedWidget güncellendiğinde widget otomatik olarak yeniden oluşturulur.
BuildContext, ağaçtaki bir öğeye bağlıdır ve öğe yok edilebilir (widget kaldırılır). Widget kaldırıldıktan sonra kaydedilmiş bir bağlam kullanmak istisnaya yol açar. Async callback’te bağlam gerekiyorsa, kullanmadan önce mounted‘ı kontrol edin.
BuildContext bir arayüz, Element ise onun uygulamasıdır. Geliştirici, belirli öğe türünü bilmeden BuildContext üzerinden çalışır. Element, Widget’ı RenderObject’a bağlayan ve yaşam döngüsünü yöneten Flutter iç mekanizmasıdır.
Başka bir widget’ın bağlamına doğrudan erişim yoktur. Ebeveyn bağlamı için State için context.findAncestorStateOfType veya anahtarlar (GlobalKey) kullanın. Çocuk için — bir callback iletin. BuildContext, hiyerarşi dışında widget’lar arası erişim için tasarlanmamıştır.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun