Flutter: Center Widget Detaylı Kullanımı
Son güncelleme:
4 dk okuma

Center, tek bir çocuğu içinde bulunduğu alanın tam ortasına koyar; teknik olarak alignment: Alignment.center ile sabitlenmiş bir Align'dır ve aynı boyut kurallarını taşır. Yükleme göstergesi, boş liste mesajı, giriş formu, dialog içeriği: "ortala" dediğiniz her yerde ilk uzandığınız widget budur. Basit görünmesine rağmen "Column içinde neden dikeyde ortalamadı?", "neden tüm ekranı kapladı?", "kaydırılabilir sayfada nasıl ortalarım?" soruları sık sorulur; bu yazı tam olarak onlara cevap veriyor.
Canlı Demo: Center Widget Örnekleri
Aşağıdaki interaktif örnekte Center widget'ını farklı senaryolarda deneyebilirsiniz:
💡 Eğer yukarıdaki örnek açılmazsa, DartPad linkine tıklayarak yeni sekmede çalıştırabilirsiniz.
Temel Kullanım
Scaffold(
body: Center(
child: CircularProgressIndicator(),
),
)Center hem yatayda hem dikeyde ortalar ve tek bir child alır. Scaffold body'si sınırlı bir alan verdiği için Center tüm gövdeyi kaplar, gösterge de ekranın tam ortasına oturur. Bu en yaygın kullanımdır ve neredeyse hiç sürpriz yapmaz; sürprizler Center'ı Column, Row veya kaydırılabilir bir widget'ın içine koyduğunuzda başlar.
Center Neden Tüm Alanı Kaplar?
Center'ın boyutu Align ile aynı kurala uyar: parent bir eksende sınır veriyorsa Center o eksende mümkün olan en büyük boyutu alır; sınır vermiyorsa çocuğu kadar olur. Ortalamak için etrafta boşluk gerekir, bu yüzden "olabildiğince büyü" varsayılan davranıştır. Flutter Inspector'da Center'ı seçtiğinizde mavi alanın tüm parent'ı kapladığını görürsünüz; bu bir hata değildir.
Bu davranışı widthFactor ve heightFactor ile değiştirebilirsiniz:
Center(
widthFactor: 1, // Center genişliği = çocuğun genişliği
heightFactor: 2, // Center yüksekliği = çocuğun yüksekliğinin iki katı
child: Text('Sıkı sarılmış'),
)widthFactor: 1 ve heightFactor: 1 verirseniz Center çocuğuna sıkı sarılır; ortalama etkisi kaybolur ama parent'ı doldurmadığı için örneğin bir Stack'i büyütmez. 2 gibi bir değer, çocuğun etrafında kendi boyutuna oranlı boşluk bırakır.
Column İçinde Center
Column çocuklarına yatayda sınırlı, dikeyde sınırsız alan verir. Bu yüzden Column içindeki Center tam genişlikte ama çocuğu kadar yüksekliktedir: yalnızca yatayda ortalar. Dikeyde ortalamak istiyorsanız iş Column'un kendisine düşer:
// Yatayda ortalar, dikeyde ortalamaz
Column(
children: [
Center(child: Text('Sadece yatayda ortada')),
],
)
// Tüm çocukları dikeyde ortalar
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Dikeyde ortada'),
],
)
// Column'un tamamını her iki eksende ortalar
Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.inbox, size: 64),
SizedBox(height: 16),
Text('Henüz içerik yok'),
],
),
)Üçüncü örnekteki mainAxisSize: MainAxisSize.min kritik: Column varsayılan olarak dikeyde alabildiği kadar uzar, o zaman Center'ın ortalayacağı boşluk kalmaz. Bu davranışı mainAxisSize yazısında ayrıntılı anlattım. Column içinde tek bir çocuğu yatayda ortalamak için Center yerine crossAxisAlignment: CrossAxisAlignment.center de kullanılabilir; fark, crossAxisAlignment'ın tüm çocukları etkilemesidir.
Row İçinde Center
Row yatayda sınırsız alan verir; Center çocuğu kadar daralır ve ortalayacak boşluk kalmaz. Row içinde "bu metni ortala" istiyorsanız Center'ı bir Expanded içine alın; Expanded, Center'a sınırlı bir alan verir ve ortalama çalışır:
Row(
children: [
Icon(Icons.arrow_back),
Expanded(
child: Center(child: Text('Başlık')),
),
Icon(Icons.more_vert),
],
)İki ikonun arasında kalan tüm genişlik Center'a gider, başlık o alanın ortasına oturur. Expanded'ın bu işi neden yaptığını Expanded yazısında bulabilirsiniz.
Ne Zaman Kullanılır, Ne Zaman Kullanılmaz?
Center'a uzanın:
- Tek bir widget'ı sınırlı bir alanın ortasına koymak için (Scaffold body, Container, Card, Expanded).
- Dialog, boş durum, yükleme ekranı gibi "ortada tek bir şey var" düzenlerinde.
- Bir Stack veya SizedBox içinde çocuğu ortalarken.
Başka araca geçin:
- Merkez dışında bir konum için
Align. - Row veya Column'daki tüm çocukları hizalamak için
mainAxisAlignmentvecrossAxisAlignment. - Zaten bir Container varsa
Container(alignment: Alignment.center); ayrı bir Center eklemeye gerek yok. - Çok satırlı bir metnin satırlarını ortalamak için
textAlign: TextAlign.center; Center metin kutusunu ortalar, kutunun içindeki satırları değil.
Sık Yapılan Hatalar
1. SingleChildScrollView içinde Center dikeyde ortalamıyor
Belirti: Kısa bir form, kaydırılabilir sayfada üste yapışık duruyor. SingleChildScrollView dikeyde sınırsız alan verir; Center çocuğu kadar olur ve ortalayacak alanı yoktur. Çözüm: Center'ı kaydırılabilir alanın dışına almak (aşağıdaki senaryo) ya da içeriğe en az ekran yüksekliği vermek:
LayoutBuilder(
builder: (context, constraints) => SingleChildScrollView(
child: ConstrainedBox(
constraints: BoxConstraints(minHeight: constraints.maxHeight),
child: Center(child: Text('Kısa içerik ortada, uzun içerik kayar')),
),
),
)2. Center içindeki Column tüm yüksekliği kaplıyor
Belirti: Center(child: Column(...)) yazdınız, içerik yine üstten başlıyor. Column'un mainAxisSize varsayılanı max; Center'ın verdiği tüm yüksekliği alır. mainAxisSize: MainAxisSize.min ekleyin ya da Column'un kendi mainAxisAlignment: center ayarını kullanın.
3. Uzun metin ortalanmış görünmüyor
Belirti: Metin kutusu ortada ama satırlar sola yaslı. Center, Text widget'ının kutusunu ortalar; kutu genişliğe sığmayıp sarıldığında satırlar varsayılan olarak sola hizalanır. Text('...', textAlign: TextAlign.center) verin.
4. Stack içinde Center'ın Stack'i büyütmesi
Belirti: Küçük bir ikonun üstüne ortalanmış bir katman koymak istediniz, Stack tüm ekrana yayıldı. Center sınırlı alanda büyüdüğü için Stack de büyür. Stack'e SizedBox ile boyut verin ya da Center'a widthFactor: 1, heightFactor: 1 ekleyin; Align'daki aynı sorunu ve Positioned alternatifini Align yazısında, Stack'in boyut kurallarını ise Stack ve Positioned yazısında anlattım.
Mini Senaryo: Ortalanmış ve Kaydırılabilir Giriş Ekranı
Bir giriş ekranı düşünün: büyük ekranda form ortada dursun ve 400 pikselden geniş olmasın; küçük ekranda klavye açılınca içerik kaydırılabilsin.
class LoginScreen extends StatelessWidget {
const LoginScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: SingleChildScrollView(
padding: const EdgeInsets.all(24),
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 400),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const FlutterLogo(size: 72),
const SizedBox(height: 32),
const TextField(decoration: InputDecoration(labelText: 'E-posta')),
const SizedBox(height: 16),
const TextField(
obscureText: true,
decoration: InputDecoration(labelText: 'Şifre'),
),
const SizedBox(height: 24),
FilledButton(onPressed: () {}, child: const Text('Giriş Yap')),
],
),
),
),
),
),
);
}
}Sıralama bilinçli: Center dışta, SingleChildScrollView içte. Center, Scaffold'dan sınırlı alanı alır ve büyür; SingleChildScrollView içeriği kadar olur ve Center onu ortalar. İçerik ekrandan uzunsa kaydırma alanı tüm yüksekliği alır ve kaydırılabilir; klavye açıldığında Scaffold gövdeyi küçültür, aynı mekanizma çalışır. ConstrainedBox(maxWidth: 400) tablette formun uçsuz bucaksız genişlemesini engeller; mainAxisSize: MainAxisSize.min ise Column'un yalnızca içeriği kadar yer kaplamasını sağlar. Padding'i SingleChildScrollView.padding olarak verdim ki kenar boşlukları kaydırma alanına dahil olsun; ayrıntısı Padding yazısında.
Sık Sorulan Sorular
Center ile Align arasındaki fark nedir?
Fark yoktur: Center, alignment: Alignment.center ile sabitlenmiş bir Align'dır; widthFactor ve heightFactor parametreleri ve boyut kuralları aynıdır. Yalnızca ortalıyorsanız Center daha okunur; başka bir konum gerekiyorsa Align kullanın.
Center neden çocuğundan büyük?
Parent sınırlı bir alan verdiğinde Center o alanın tamamını kaplar; ortalama ancak etrafta boşluk varsa anlamlıdır. Çocuğuna sıkı sarılmasını istiyorsanız widthFactor: 1 ve heightFactor: 1 verin.
Column içinde Center neden dikeyde ortalamıyor?
Column dikeyde sınırsız alan verir; Center ortalayacak yükseklik bulamaz ve çocuğu kadar olur. Column'a mainAxisAlignment: MainAxisAlignment.center verin ya da Column'u mainAxisSize: MainAxisSize.min ile Center içine alın.
Center mı mainAxisAlignment mı kullanmalıyım?
Tek bir çocuğu her iki eksende ortalamak için Center; Row veya Column'daki birden fazla çocuğu ana eksende hizalamak (center, spaceBetween, spaceEvenly) için mainAxisAlignment. İkisi birlikte de kullanılabilir: Center dış kutuyu, mainAxisAlignment içerideki çocukları hizalar.
İlgili Yazılar
Flutter: Align Widget ile İnce Hizalama İşlemleri
Align ile hassas hizalama: Alignment(x, y) koordinat sistemi, FractionalOffset, widthFactor ve heightFactor, Stack içinde Align mı Positioned mı, hatalar.
Flutter: ListView Widget Kullanımı
Flutter ListView rehberi: builder ile tembel listeleme, separated, itemExtent, shrinkWrap maliyeti ve unbounded height hatasının çözümü.
Flutter: GridView Widget Kullanımı
Flutter GridView rehberi: count, extent ve builder kurucuları, iki grid delegate'in farkı, childAspectRatio taşma hatası ve shrinkWrap maliyeti.