Widget Tree: nedir, yapısı ve widget ağacındaki rolü

Yazar: IT Sectr Yayınlanma: 2026-07-01 Okuma süresi: 10 dk

Widget Tree, Flutter'da kullanıcı arayüzünün düzenini tanımlayan hiyerarşik bir widget yapısıdır. Bir düğmeden tüm ekrana kadar arayüzün her öğesi, bir üst kapsayıcı içinde iç içe geçmiş ayrı bir widget ile temsil edilir. Flutter, her durum değişikliğinde Widget Tree'yi günceller — çerçeve yeni ve eski ağacı karşılaştırır ve minimum değişiklik uygular. Flutter Team, 2025'e göre, verimli bir ağaç yapısı animasyonların akıcılığını ve arayüz yanıt verme hızını doğrudan etkiler.

Önemli Noktalar

  • Widget Tree, her Flutter widget'ının bir düğüm olduğu ve iç içe geçmenin UI düzenini yansıttığı bir hiyerarşidir.
  • Her yeniden oluşturma (rebuild) widget yapılandırmasını yeniden oluşturur, ancak ekranı mutlaka yeniden çizmez — Element ve RenderObject bununla ilgilenir.
  • StatelessWidget iç duruma sahip değilken, StatefulWidget ağacın yeniden oluşturulmasını etkileyen verileri depolar.
  • Anahtarlar (Key), Flutter'ın yeniden yapılanma sırasında widget'ları tanımlamasına yardımcı olarak durum kaybını önler.
  • Ağaç derinliği performansı etkiler — aşırı iç içe geçme, oluşturmanın düzen aşamasını yavaşlatabilir.

Flutter'da Widget Tree Nedir?

Widget Tree, Flutter'da kullanıcı arayüzünün bildirimsel bir tanımıdır ve iç içe geçmiş widget'lardan oluşan bir ağaç olarak inşa edilir. Her widget, UI'nin bir bölümünü tanımlar: yapılandırması, görüntüleme parametreleri ve etkileşim sırasındaki davranışı. Geliştirici, mevcut uygulama durumunda arayüzün nasıl görünmesi gerektiğini tanımlar ve Flutter bu tanımı ekrandaki piksellere dönüştürmeyi üstlenir.

Flutter'ın Bildirimsel Yaklaşımı

Geliştiricinin arayüz öğelerini doğrudan manipüle ettiği emir kipi çerçevelerinin aksine, Flutter bildirimsel bir yaklaşım kullanır. Uygulama durumu değiştiğinde yeni bir Widget Tree oluşturulur ve çerçeve eski ile yeni ağaç arasındaki farkı hesaplar. Bu, oluşturma işlemlerinin sayısını en aza indirir ve kodu daha öngörülebilir hale getirir.

dart
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text("Widget Tree")),
        body: Center(
          child: Column(
            children: [
              Text("Merhaba, Flutter"),
              ElevatedButton(
                onPressed: () {},
                child: Text("Bana bas"),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

Bu örnekte Widget Tree, MaterialApp, Scaffold, AppBar, Center, Column, Text ve ElevatedButton'dan oluşur. Bu widget'ların her biri ağaçta bir düğümdür. Uygulama durumu değiştiğinde Flutter, build yöntemini yeniden çağırır ve sonucu önceki ağaçla karşılaştırır.

Widget Tree Yapısı: Kök ve Alt Widget'lar

Widget Tree, runApp yöntemine iletilen bir kök widget ile başlar. Kök widget genellikle MaterialApp, CupertinoApp veya WidgetsApp'tir — uygulamanın genel ayarlarını belirler. Kökten ağaç, her biri kendi alt öğelerini içerebilen alt widget'lara dallanır.

Tek Alt ve Çoklu Alt Widget'lar

Flutter'daki widget'lar tek-alt (single-child) (child parametresi aracılığıyla bir alt öğe kabul eder) ve çoklu-alt (multi-child) (children aracılığıyla bir alt öğe listesi kabul eder) olarak ikiye ayrılır. Tek-alt örnekleri: Center, Padding, SizedBox, Container. Çoklu-alt: Column, Row, Stack, ListView, GridView. Bu fark, Widget Tree yapısını etkiler: çoklu-alt widget'lar daha geniş ağaçlar oluştururken, tek-alt widget'lar daha derin ağaçlar oluşturur.

Ağaçta BuildContext'in Rolü

BuildContext, Widget Tree'de bir widget'ın konumudur. Her widget'ın kendi BuildContext'i vardır, bu build yöntemine iletilir ve üst widget'lara, temaya, MediaQuery'ye ve diğer InheritedWidget'lara erişmek için kullanılır. BuildContext, widget ile Element Tree'deki öğesi arasında bir köprü görevi görür.

dart
class MyWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final theme = Theme.of(context);
    final mediaQuery = MediaQuery.of(context);
    return Container(
      color: theme.colorScheme.primary,
      child: Text(
        "Ekran genişliği: ${mediaQuery.size.width}"
      ),
    );
  }
}

Bu örnekte, BuildContext tema ve ekran boyutlarını almak için kullanılır. Flutter, InheritedWidget olan en yakın Theme ve MediaQuery'ye kadar Widget Tree'de yukarı çıkar. Bu, bağlamın bir widget'ı hiyerarşideki konumuna nasıl bağladığını gösterir.

Flutter Başlangıçta Widget Tree'yi Nasıl Oluşturur

Bir Flutter uygulaması başlatıldığında, kök widget'ı alan ve Widget Tree'yi oluşturmaya başlayan runApp işlevi çağrılır. Süreç üç aşamadan oluşur: widget yapılandırması oluşturma, Element Tree'yi oluşturma ve gerçek oluşturma için RenderObject Tree'yi inşa etme.

Aşama 1: Kök Widget'ı Oluşturma

runApp işlevi, çerçeveyi grafik motoruna bağlayan WidgetsFlutterBinding aracılığıyla bir kök öğe oluşturur. Kök widget ağaca yerleştirilir ve Flutter, onu alt widget'larla doldurmak için build yöntemini çağırır. Her build çağrısı, Widget Tree'nin yeni bir alt grafiğini oluşturur.

Aşama 2: İlk Düzen (Layout)

Widget Tree'yi oluşturduktan sonra Flutter, tüm widget'ların boyutlarını ve konumlarını hesaplayan bir ilk düzen gerçekleştirir. Bu süreç kökten başlar ve ağaçta aşağı doğru yayılır. Her widget, üst öğesinden kısıtlamalar alır ve hesaplanmış bir boyut döndürür. Boyutlar eşleşmezse Flutter bir düzen hatası oluşturur.

Aşama 3: Ekranda Oluşturma

Düzen tamamlandıktan sonra Flutter, her widget'ı oluşturmaya devam eder. RenderObject, arayüz tanımını GPU tarafından Skia veya Impeller aracılığıyla yürütülen grafik komutlarına dönüştürür. Widget Tree'den piksellere kadar tüm süreç, saniyede 120 kareye kadar her durum değişikliğinde tekrarlanır.

Ağaç Hiyerarşisinde StatelessWidget ve StatefulWidget

StatelessWidget, iç değişebilir durumu olmayan bir widget'tır. Görünümü tamamen kurucu aracılığıyla iletilen giriş parametreleri tarafından belirlenir. Parametreler değişmediyse StatelessWidget yeniden oluşturulmaz. Bu, onu performans açısından hafif yapar.

StatelessWidget Ne Zaman Kullanılır

Simgeler, metin etiketleri, dekoratif ayırıcılar ve iç mantığı olmayan basit düğmeler gibi statik arayüz öğeleri için StatelessWidget kullanın. Flutter dokümantasyonuna göre, tipik bir uygulamadaki widget'ların yaklaşık %70'i StatelessWidget olabilir, bu da çöp toplayıcı yükünü azaltır ve yeniden oluşturmaları hızlandırır.

StatefulWidget ve Durum Yönetimi

StatefulWidget, widget yeniden oluşturmaları arasında kalıcı olan bir State nesnesi oluşturur. Durum değiştiğinde (setState aracılığıyla), Flutter widget'ı “kirli” olarak işaretler ve bir sonraki karede yeniden oluşturur. StatefulWidget, etkileşimli öğeleri (giriş alanları, animasyonlar, zamanlayıcılar ve dinamik listeler) mümkün kılar.

dart
class CounterWidget extends StatefulWidget {
  @override
  State<CounterWidget> createState() => _CounterWidgetState();
}

class _CounterWidgetState extends State<CounterWidget> {
  int _count = 0;

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text("Sayı: $_count"),
        ElevatedButton(
          onPressed: () {
            setState(() => _count++);
          },
          child: Text("Artır"),
        ),
      ],
    );
  }
}

Bu örnekte, StatefulWidget sayacı güncellemek için setState kullanır. Durum güncellendiğinde Flutter, Widget Tree'nin yalnızca değişen kısmını — CounterWidget ve alt öğelerini — yeniden oluşturur. Üst widget'lar yeniden oluşturulmaz, bu Flutter'ın bildirimsel modelinin önemli bir avantajıdır.

Widget Tree, Element Tree ile Nasıl İlişkilidir

Widget Tree yapılandırma katmanıdır, Element Tree ise widget'lar ile gerçek oluşturma arasındaki ara bağlantıdır. Widget Tree'deki her widget, Element Tree'de widget'a bir referans depolayan ve yaşam döngüsünü yöneten bir öğe oluşturur. Bu mimari, Flutter'ın değişiklikleri verimli bir şekilde ele almasını sağlar.

Bir Widget'tan Öğe Oluşturma

Flutter bir widget ile ilk karşılaştığında, karşılık gelen bir öğe oluşturan createElement yöntemini çağırır. StatelessWidget için StatelessElement oluşturulur; StatefulWidget için StatefulElement oluşturulur ve bu ayrıca bir State nesnesi oluşturur. Öğe, widget yeniden oluşturulsa bile yeniden oluşturma döngüleri arasında kalıcı olur.

Element Tree'de Anahtarların (Keys) Mekanizması

Key, Flutter'ın eski ve yeni Widget Tree'den widget'ları eşleştirmesine yardımcı olan bir tanımlayıcıdır. Bir widget'ın Key'i varsa Flutter, ağaçtaki konumu yerine karşılık gelen öğeyi bulmak için bunu kullanır. Öğelerin sırasının değişebileceği dinamik listelerle çalışırken anahtarlar gereklidir.

dart
ListView(
  children: items.map((item) => ListItem(
    key: ValueKey(item.id),
    data: item,
  )).toList(),
)

Key olmadan Flutter, öğeleri konuma göre eşleştirir; bu, sıra değiştiğinde yanlış durum korumaya yol açabilir. Benzersiz tanımlayıcıya sahip ValueKey, her öğenin listedeki konumundan bağımsız olarak durumunu korumasını sağlar.

Widget Tree'nin Performansa Etkisi

Widget Tree yapısı, Flutter uygulamasının performansını doğrudan etkiler. İç içe geçmiş birçok widget'a sahip derin ağaçlar, düzen aşaması için daha fazla zaman gerektirir ve bellek kullanımını artırır. Flutter DevTools, Widget Tree'yi analiz etmek ve darboğazları belirlemek için araçlar sağlar.

Aşırı İç İçe Geçme

Her iç içe geçme seviyesi, düzen ve boyama sırasında ek hesaplamalar ekler. Derin zincir iç içe geçme yerine daha düz yapılar kullanın. Örneğin, Expanded ile Row, Align ile birden çok iç içe Container'ın yerini alabilir. Flutter Team'e göre ağaç optimizasyonu, düzen süresini %40'a kadar azaltabilir.

  • Düzen — her üst, alt widget'lara kısıtlamalar iletir ve boyutları geri alır; derin iç içe geçme ile bu bir hesaplama zinciri oluşturur.
  • Boyama — her widget oluşturma için ayrı bir katman oluşturabilir ve aşırı iç içe geçme katman sayısını artırır.
  • Bellek — Element Tree'deki her öğe bellek kaplar ve aşırı widget'lar kaynak tüketimini artırır.

Widget Tree'yi Analiz Etme Araçları

Flutter DevTools, mevcut Widget Tree'yi gerçek zamanlı olarak gösteren “Widget Inspector” aracını sağlar. Geliştirici, ekrandaki herhangi bir widget'ı seçebilir ve ağaçtaki yerini, parametrelerini ve düzen kısıtlamalarını görebilir. Bu, beklenmeyen iç içe geçmeyi, aşırı yeniden oluşturmaları ve boyutlandırma sorunlarını belirlemeye yardımcı olur.

Optimizasyon için RepaintBoundary

RepaintBoundary, bağımsız oluşturma için Widget Tree'nin bir bölümünü izole eden bir widget'tır. RepaintBoundary içindeki içerik değişirse, tüm ekran değil yalnızca kendi alanı yeniden boyanır. Animasyonlar, listeler ve sık güncellenen diğer öğeler için RepaintBoundary kullanın.

dart
RepaintBoundary(
  child: CustomPaint(
    painter: MyPainter(),
    child: SizedBox(
      width: 200,
      height: 200,
    ),
  ),
)

Bu örnekte, RepaintBoundary CustomPaint'i ayrı bir oluşturma alanına izole eder. Bu alan içindeki animasyon güncellendiğinde, yalnızca CustomPaint widget'ı yeniden boyanır, ekranın geri kalanı değişmez. Bu, birden çok animasyonlu öğeye sahip karmaşık arayüzlerde özellikle kullanışlıdır.

Sıkça Sorulan Sorular

Widget Tree, Element Tree'den nasıl farklıdır?

Widget Tree, her yeniden oluşturmada yeniden oluşturulan bildirimsel bir arayüz tanımıdır. Element Tree güncellemeler arasında kalıcı olur ve widget'ların gerçek RenderObject'lerle yaşam döngüsünü, durumunu ve eşlemesini yönetir.

Bir Widget Tree'de kaç widget olabilir?

Widget sayısında bir sınır yoktur, ancak pratikte binlerce widget içeren bir ağaç düzen aşamasını yavaşlatabilir. Flutter, birkaç bin düğüme kadar olan ağaçlar için optimize edilmiştir; daha büyük sayılar için ListView.builder aracılığıyla sanallaştırma önerilir.

Hata ayıklayıcıda Widget Tree nasıl görülür?

Flutter DevTools — “Widget Inspector” sekmesini kullanın. Uygulamayı hata ayıklama modunda çalıştırın, tarayıcıda DevTools'u açın ve Widget Tree'deki yerini görmek için ekrandaki herhangi bir widget'ı seçin.

Widget Tree yeniden oluşturma (rebuild) nedir?

Yeniden oluşturma, durum değiştiğinde widget yapılandırmasını yeniden oluşturma sürecidir. Flutter, değişen widget'lar için build yöntemini yeniden çağırır, yeni Widget Tree'yi öncekiyle karşılaştırır ve Element Tree'ye minimum değişiklik uygular.

Widget Tree nasıl optimize edilir?

İç içe geçme derinliğini azaltın, statik öğeler için const widget'lar kullanın, animasyonları izole etmek için RepaintBoundary uygulayın ve StatelessWidget'ın yeterli olduğu yerlerde aşırı StatefulWidget'lardan kaçının.

Özet

  • Widget Tree, Flutter'da UI'nin hiyerarşik bildirimsel bir tanımıdır ve her düğüm yapılandırma ve parametrelere sahip bir widget'tır.
  • Flutter, başlangıçta runApp aracılığıyla Widget Tree'yi oluşturur ve üç aşama yürütür: kök widget oluşturma, düzen ve oluşturma.
  • StatelessWidget duruma sahip değildir ve yalnızca giriş parametreleri değiştiğinde yeniden oluşturulur; StatefulWidget dinamik verileri yönetmek için setState kullanır.
  • Element Tree yeniden oluşturmalar arasında kalıcı olur ve öğeler aracılığıyla Widget Tree'yi RenderObject Tree'ye bağlar.
  • Anahtarlar (Key) yeniden oluşturma sırasında doğru widget eşleşmesini sağlar, özellikle dinamik listelerde.
  • Ağaç derinliği performansı etkiler — aşırı iç içe geçme düzen süresini ve bellek tüketimini artırır.
  • RepaintBoundary yerel yeniden boyama için Widget Tree'nin bir bölümünü izole eder ve animasyonlar sırasında GPU yükünü azaltır.

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.

Projeyi tartış

Ayrıca okuyun