Flutter: Herkesin Bilmesi Gereken Temel Layout Kuralları

Suat Özkaya
14 min readSep 2, 2021

Dikkat: Bu yazı Marcelo Glasberg tarafından yazılmış ve Flutter resmi dokümanlarının da bir parçası olan ‘Flutter: The Advanced Layout Rule Even Beginners Must Know’ adlı makalenin tarafımdan Türkçeye çevirisidir.

Bu çalışmaya izin verdiğin için teşekkürler Marcelo!

Flutter öğrenen biri width:100 genişliğinde olan bir widget’ın neden 100 piksel olmadığını sorduğunda ne dersiniz? Widget’ı bir Center ile sarmasını (wrapping), değil mi?

Hayır bunu yapmayın!

Çünkü bunu yaparsanız size “FittedBoxneden çalışmıyor?”, “Column neden ekrandan taşıyor (overflowing)?” veya “ IntrinsicWidthneye yarar?” gibi sorularla tekrar tekrar gelecektir.

Bunun yerine ona Flutter Layout kurallarının HTML dünyasından çok farklı olduğunu anlatın (ki muhtemelen oradan gelmiştir), ve şu kuralı ezberletin.

👉 Kısıtlamalar aşağı, boyutlar yukarı akar. Pozisyonu parent belirler.

Bu kural bilinmeden Flutter layoutu gerçekten anlaşılamaz, bu yüzden bunun erkenden öğrenilmesi gerektiğine inanıyorum.

Biraz daha açarsak:

  • Bir widget kendi kısıtlamalarını (constraints) parent widget’ından alır. Bir “kısıtlama” yalnızca 4 özellik tarafınan belirlenir: minimum & maksimum genişlik ve minimum & maksimum yükseklik.
  • Ardından, bu widget çocuklarının (children) üzerinden bir bir geçer. Çocuklarına sırasıyla kısıtlamalarının ne olduğunu (her çocuk için farklı olabilir) söyler ve ardından her çocuğa hangi boyutta olmak istediğini sorar.
  • Sonrasında ise, widget çocuklarını (yatay olarak x ekseninde ve dikey olarak y ekseninde) birer birer konumlandırır.
  • En sonunda, parent widget’ına kendi boyutunu söyler (elbette orijinal kısıtlamalar dahilinde).

Örneğin, Padding içeren bir Column ve iki çocuğunun yerleşimini ele alalım:

Column Widget’ımız ile çocukları (children) ve parent’ı arasında şu şekilde bir iletişim gerçekleşir:

Widget: Hey parent, kısıtlamalarım neler?

Parent: Genişliğin 90 ve 300 piksel aralığında, uzunluğun ise 30 ve 85 piksel aralığında olmalı

Widget: Hmm, bana 5 piksel padding gerekiyor. Bu durumda çocuklarımın yerleşeceği alan en fazla 295 piksel genişlik, 75 piksel yükseklikte olabilir.

Widget: Hey ilk çocuğum (mor kutu-first child), sen 0-290 genişlik ve 0-75 yükseklik aralığında olmalısın.

İlk Çocuk: Peki, öyleyse 290 piksel genişlik ve 20 piksek yükseklikte olmak isterim.

Widget: Hm, ikinci çocuğumu ilkinin altına, sütun olarak yerleştirmeliyim. Bu durumda ikinci çocuğuma sadece 55 piksek yükseklikte alan kalıyor.

Widget: Hey ikinci çocuk (yeşil kutu), sen 0-290 genişlik ve 0-55 yükseklik aralığında olmalısın.

İkinci Çocuk: 140 piksel genişlik ve 30 piksek yükseklikte olmak isterim.

Widget: Çok güzel, bu durumda pozisyon olarak da ilk çocuğum x:5, y:5 posizyonunda yerleşebilir. İkinci çocuğum ise x:80, y:25 pozisyonuna yerleşebilir.

Tüm bu iletişim ve hesaplardan sonra Column Widget’ımız bu kez kendi parent Widget’ına dönerek ihtiyacı olan alanı bildirir.

Widget: Hey parent, benim 300 piksel genişlik ve 60 piksel yüksekliğe ihtiyacım var.

(çn. Bu örnekte, Column çocuklarını ortalamaya çalışıyor, ayrıca bu pozisyonlar Column Widget’ının kendi alanın sol üst köşesini X=0,Y=0 kabul ettiğimizde ortaya çıkan bağıl koordinatlardır)

Limitler

Yukarıda açıklanan yerleşim kuralının bir sonucu olarak, Flutter’ın bir kaç önemli yerleşim sınırlaması vardır:

  • Bir Widget istediği herhangi bir boyuta sahip olamaz. Parent’ın ona dayatacağı kısıtlamalar olabilir ve boyutu işte bu kısıtlamalar dahilinde kalacaktır.
  • Bir Widget ekranda nerede belireceğini bilemez ve buna kendi karar veremez. Bu karar parent Widget tarafından verilir.
  • Bu kuralların bir sonucu olarak, bir parent’ın pozisyonu ve boyutları da kendi parent’a bağlıdır. Bu yüzden tüm widget ağacını göz önüne alıp hesaplamalar yapmadan ekranda öğelerin nerede belireceğini bilmek mümkün değildir.

Örnekler:

Örnek 1

Container(color:Colors.red)

Bu container’ın parent öğesi cihaz ekranı. Ekran Container ‘ı kendiyle aynı boyutta olmaya zorlar. Neticede, Container tüm ekranı kaplar ve her yer kırmızı olur.

Örnek 2

Container(width: 100, height: 100, color: Colors.red)

Kırmızı Container 100 x 100 boyutlarında olmak ister, ancak olamaz. Çünkü parentı olan ekran, onu tüm ekranı doldurmaya zorlar. Container tüm ekranı kaplar ve her yer kırmızı olur.

Örnek 3

Center(
child: Container(width: 100, height: 100, color: Colors.red)
)

Burada ekran Center ‘ı ekranı doldurmaya zorlar ve Center ekranı doldurur.

Center çocuğu olan Container ‘a ekran boyutu kısıtı dahilinde hangi boyutta olmak istediğini sorar. Burada Container istediği şekilde 100 x 100 boyutunu seçebilir.

Örnek 4

Align(
alignment: Alignment.bottomRight,
child: Container(width: 100, height: 100, color: Colors.red),
)

Bu örnekte Center yerine Align kullanılmış.

Align çocuğu Container a istediği boyutta olabileceğini söyler, gelen yanıta göre eğer müsait alan varsa onu ekran ortasına koymak yerine sağ-alt köşeye hizalar.

Örnek 5

Center(
child: Container(
color: Colors.red,
width: double.infinity,
height: double.infinity,
)
)

Center ekran tarafından tüm alanı kaplamaya zorlanır, ve tüm ekranı Center ile dolar.

Container ‘a ekran boyutları kısıtlaması dahilinde ne kadar alan istediği sorulur. Container sonsuz boyutta olmak ister, ancak Center tarafından ona verilen kısıtlama ekran boyutlarıdır. Neticede Container ekran boyutlarını geçemez ve tüm ekranı kırmızı yapacak şekilde kaplar.

Örnek 6

Center(child: Container(color: Colors.red))

Center ekran tarafından tüm alanı kaplamaya zorlanır, ve Center tüm ekranı kaplar.

Container ‘a ekran boyutları kısıtlaması dahilinde ne kadar alan istediği sorulur. Container için herhangi bir çocuk widget veya boyutlama tanımlanmamıştır. Bu durumda Container olabildiğince büyük olmayı seçer ve tüm ekranı kaplar.

Peki Containerneden bu kararı verir? Bu bir tasarım kararıdır, yani Container widgetı tasarlanırken bu şekilde davranmasını kararı verilmiştir. Elbette bu karar başka şekilde de verilebilirdi. Container ‘ın hangi koşullarda nasıl davranacağı kararları için ilgili dokümanını okumanız gerekiyor.

Örnek 7

Center(
child: Container(
color: Colors.red,
child: Container(color: Colors.green, width: 30, height: 30),
)
)

Center ekran tarafından tüm alanı kaplamaya zorlanır, ve Center tüm ekranı kaplar.

Container ‘a ekran boyutları kısıtlaması dahilinde ne kadar alan istediği sorulur. Container için herhangi bir boyutlama tanımlanmamıştır ancak bir çocuğu vardır. İşte bu durumda Container çocuğu boyutunda olmayı seçer. [Bu da bir önceki örnekteki gibi bir tasarım kararıdır. (ç.n.)]

Kırmızı Container çocuğuna istediği boyutu seçebileceğini ancak ekran boyutu kısıtlaması olduğunu söyler. Yeşil Container boyutunu 30 x 30 olarak bildirir.

Neticede, yeşil Container istediği boyut olan 30 x 30 alanı alır, kırmızı Container çocuğu kadar alan kaplamayı tercih ettiğinden o da 30 x 30 alan kaplar. Ancak bunlar aynı boyutta olduğundan yeşil ekranda üstte kalır ve kırmızı bize görünmez.

Örnek 8

Center(
child: Container(
color: Colors.red,
padding: const EdgeInsets.all(20.0),
child: Container(color: Colors.green, width: 30, height: 30),
)
)

Kırmızı Container kendini çocuğu kadar boyutlandırmak ister, ancak kendine verilen padding de hesaba katılmalıdır. Bu yüzden 70 x 70 boyutlarında olmaya karar verir (30 x 30 üzerine her kenardan 20 piksel padding eklenmekte). Bu padding sebebiyle boyutları artan kırmızı Container yeşilin arkasından bu kez görülebilmektedir.

Örnek 9

ConstrainedBox(
constraints: BoxConstraints(
minWidth: 70,
minHeight: 70,
maxWidth: 150,
maxHeight: 150,
),
child: Container(color: Colors.red, width: 10, height: 10),
)

Container ‘ın 70 –150 piksel arasında olacağını tahmin edebilirsiniz, çünkü ConstrainedBox tarafından getirilen kısıtlamalar bunlar olarak görülüyor. Ancak ConstrainedBox kendi parent widget’ından gelen kısıtlamalara ilaveler ekleyebilir.

Burada, ConstrainedBox ekran tarafından tüm ekran boyutunda olmaya zorlanır ve ilave constraints parametresini göz ardı ederek kısıtlama olarak Container ‘a tüm ekran boyutu kısıtlamasını iletir.

Örnek 10

Center(
child: ConstrainedBox(
constraints: BoxConstraints(
minWidth: 70,
minHeight: 70,
maxWidth: 150,
maxHeight: 150,
),
child: Container(color: Colors.red, width: 10, height: 10),
)
)

Burada ConstrainedBox istediği boyutu seçme özgürlüğüne sahiptir, çünkü Center onu bu konuda kısıtlamayacaktır. ConstrainedBox ise çocuğu olan Container ‘a ilave constraints parametresini empoze eder.

Nihayetinde Container 70 ve 150 piksel arasında olmalıdır. Container 10 piksel olmak ister ancak bu kısıtlamadan dolayı 70 (minimum değer) boyutunu alır.

Örnek 11

Center(
child: ConstrainedBox(
constraints: BoxConstraints(
minWidth: 70,
minHeight: 70,
maxWidth: 150,
maxHeight: 150,
),
child: Container(color: Colors.red, width: 1000, height: 1000),
)
)

Burada ConstrainedBox Center tarafından kısıtlanılmaz. ConstrainedBox ise çocuğu olan Container ‘a ilave constraints parametresini empoze eder.

Nihayetinde Container 70 ve 150 piksel arasında olmalıdır. Container 1000 piksel olmak ister ancak bu kısıtlamadan dolayı 150 (maksimum değer) boyutunu alır.

Örnek 12

Center(
child: ConstrainedBox(
constraints: BoxConstraints(
minWidth: 70,
minHeight: 70,
maxWidth: 150,
maxHeight: 150,
),
child: Container(color: Colors.red, width: 100, height: 100),
)
)

Bu örnekte de ConstrainedBox Center tarafından kısıtlanmamıştır ve çocuğu olan Container ‘a ilave constraints parametresini empoze eder.

Nihayetinde Container 70 ve 150 piksel arasında olmalıdır. Container 100 piksel olmak ister, bu değer kısıtlamalar dahilinde olduğu için bu isteği yerine gelir ve 100 piksel olarak ekrana boyanır.

Örnek 13

UnconstrainedBox(
child: Container(color: Colors.red, width: 20, height: 50),
)

Ekran UnconstrainedBox ‘ı tüm ekranı kaplamaya zorlar. Öte yandan UnconstrainedBox , çocuğu olan Container için her hangi bir kısıtlama getirmez.

Örnek 14

UnconstrainedBox(
child: Container(color: Colors.red, width: 4000, height: 50),
);

Ekran UnconstrainedBox ‘ı tüm ekranı kaplamaya zorlar. Öte yandan UnconstrainedBox , çocuğu olan Container için her hangi bir kısıtlama getirmez.

Kısıtlaması olmayan Container 4000 piksel genişliğe sahiptir ve ekran kadar olan UnconstrainedBox ‘a sığmaz. Bu yüzden de UnconstrainedBox ekrandan taşma uyarısı (overflow warning) verir.

Örnek 15

OverflowBox(
minWidth: 0.0,
minHeight: 0.0,
maxWidth: double.infinity,
maxHeight: double.infinity,
child: Container(color: Colors.red, width: 4000, height: 50),
);

Ekran OverflowBox ‘ı tüm ekranı kaplamaya zorlar. Öte yandan OverFlowBox , çocuğu olan Container için her hangi bir kısıtlama getirmez.

Bu şekilde bir kullanımda OverflowBox UnconstrainedBox çok benzer, aradaki fark ise ekrana sığmayan çocuğu olması durumunda OverflowBox herhangi bir taşma hatası vermez.

Örnekte Container 4000 piksel genişliktedir ve OverflowBox ‘a sığmayacağı aşikardır, yine de OverflowBox ekranda elinden geldiğince çocuğunu gösterir ve herhangi bir hata vermez.

Örnek 16

UnconstrainedBox(
child: Container(
color: Colors.red,
width: double.infinity,
height: 100,
)
)

Bu kod ekranda hiç bir şey boyamaz ve konsolda bir hata alırız.

UnconstrainedBox çocuğuna herhangi bir kısıtlama getirmez, ancak çocuğu olan Container sonsuz boyut istemektedir.

Flutter kısıtlanmamış sonsuz boyutları ekrana çizemez ve şu uyarıyı fırlatır: BoxConstraints forces an infinite width

Örnek 17

UnconstrainedBox(
child: LimitedBox(
maxWidth: 100,
child: Container(
color: Colors.red,
width: double.infinity,
height: 100,
)
)
)

Burada herhangi bir hata almayız, çünkü LimitedBox parent widgetı UnconstrainedBox ‘tan herhangi bir kısıtlama almamaktadır, yani sonsuz boyut almaktadır. Bu koşul altındaki LimitedBox kendi çocuğuna maksimum 100 piksel genişlik kısıtlaması getirmektedir.

Dikkat, eğer UnconstrainedBox yerine bir Center kullansaydık ne olurdu? LimitedBox çocuğuna bir limit kısıtlaması getiremezdi ve Container 100 piksel genişlikten daha büyük olurdu. Bunun sebebi şudur: LimitedBox ‘ın limit kısıtlaması ancak kendisi sonsuz boyut kısıtlaması altındaysa geçerli oluyor.

İşte bu da ConstrainedBox ve LimitedBox arasındaki farkı ortaya koyuyor.

Örnek 18

FittedBox(
child: Text('Some Example Text.'),
)

Ekran FittedBox ‘ı tüm ekran boyutunda olmaya zorlar. Text doğal bir genişliğe (buna intrinsic width denir) sahiptir çünkü metindeki karakter sayısı, font büyüklüğü, vb değişkenlerden etkilenir.

FittedBox Text ‘e istediği boyutta olma izni verir, ancak Text istediği boyutu FittedBox ‘a ilettikten sonra, FittedBox tarafından mevcut olan genişliğe sığdıracak şekilde tekrar boyutlandırılır.

Örnek 19

Center(
child: FittedBox(
child: Text('Some Example Text.'),
)
)

Peki FittedBox ‘ı bir Center içine yerleştirirsek ne olur? Center istediği boyutta olması için FittedBox ‘a izin verir, ekran boyutuna kadar.

FittedBox daha sonra kendisini Text ‘e göre boyutlandırır ve Text ‘in istediği boyuta sahip olmasına izin verir. Hem FittedBox hem de Text aynı ölçüdelerdir ve ilave bir boyutlandırma gerçekleşmez.

Örnek 20

Center(
child: FittedBox(
child: Text('This is some very very very large text that is too big to fit a regular screen in a single line.'),
)
)

Peki ya FittedBox bir Center içerisinde, ancak Text metni ekrana sığmayacak kadar uzun ise ne olur?

FittedBox kendini Text kadar genişletmek ister ancak ekrandan daha büyük olamaz. Bu durumda kendini ekrana göre ayarlayacak, Text ‘i ise ekrana sığacak şekilde boyutlandıracaktır.

Örnek 21

Center(
child: Text('This is some very very very large text that is too big to fit a regular screen in a single line.'),
)

Öte yandan, eğer FittedBox ‘ı aradan çıkartırsak Text ekrandan maksimum değeri alacaktır, ve ekrana sığacağı şekilde metni satırlara yayılacaktır.

Örnek 22

FittedBox(
child: Container(
height: 20.0,
width: double.infinity,
)
)

Dikkat, FittedBox sadece sınırlandırılmış (genişlik ve yüksekliği sonsuz atanmamış) bir widgetı boyutlandırabilir. Aksi halde, ekrana çizilmez ve konsola hata mesajı verilir.

Örnek 23

Row(
children:[
Container(color: Colors.red, child: Text('Hello!')),
Container(color: Colors.green, child: Text('Goodbye!)),
]
)

Ekran Row ‘u tüm ekran boyutunda olmaya zorlar.

Aynı bir UnconstrainedBox gibi davranan Row ise çocuklarına herhangi bir kısıtlama getirmez, ve istedikleri boyutu seçmelerine imkan verir. Daha sonra Row çocuklarını sırasıyla yan yana dizer, ve herhangi bir fazla alan boş olarak kalır.

Örnek 24

Row(
children:[
Container(color: Colors.red, child: Text('This is a very long text that won’t fit the line.')),
Container(color: Colors.green, child: Text('Goodbye!')),
]
)

Row çocuklarına herhangi bir kısıtlama getirmediğinden, çocukların mevcut olan genişliğe sığmayacak kadar büyük olmaları oldukça muhtemel bir durumdur. Böyle bir halde ise, UnconstrainedBox durumundaki gibi, Row ekrandan taşma uyarısı (overflow warning) verecektir.

Örnek 25

Row(
children:[
Expanded(
child: Container(color: Colors.red, child: Text('This is a very long text that won’t fit the line.'))
),
Container(color: Colors.green, child: Text('Goodbye!')),
]
)

Row ‘a bağlı bir çocuk widget Expanded ile sarmalanırsa, Row artık bu çocuğa kendi boyutunu belirleme özgürlüğü tanımaz.

Bunun yerine Expanded genişliği diğer çocuklara göre belirlenir, ve artık genişliği belli olan Expanded bu çocuğa kendi boyutuna gelmesini zorlar.

Diğer bir deyişle, Expanded kullanıldığında, orijinal çocuğun genişliği anlamsız hale gelir ve yok sayılır.

Örnek 26

Row(
children:[
Expanded(
child: Container(color: Colors.red, child: Text(‘This is a very long text that won’t fit the line.’)),
),
Expanded(
child: Container(color: Colors.green, child: Text(‘Goodbye!’),
),
]
)

Eğer Row ‘un tüm çocukları Expanded ile sarmalanırsa ne olur? Bu durumda her bir Expanded flex parametrelerine göre orantısal bir boyut alır ve sonra da her bir Expandedkendi çocuğunu bu boyuta sığmaya zorlar.

Başka bir deyişle, Expanded çocuklarının tercih ettiği genişlikleri görmezden gelir.

Örnek 27

Row(children:[
Flexible(
child: Container(color: Colors.red, child: Text('This is a very long text that won’t fit the line.'))),
Flexible(
child: Container(color: Colors.green, child: Text(‘Goodbye!’))),
]
)

Expanded yerine Flexible kullandığınızda değişecek olan şey ise şudur: Flexible çocuğuna kendiyle aynı veya daha küçük boyutta olma izni verirken Expanded ise çocuğunu kendi tam boyutuna zorlar.

Fakat hem Flexible hem de Expanded çocuklarının genişliklerini göz ardı eder.

Bunun bir anlamı da, Row çocukların orijinal boyutlarına orantılı olarak genişletilmesinin imkansız olduğudur. Row ya çocukların orijinal genişliğini kullanır, ya da Expanded ve Flexible kullanımıyla çocukların orijinal genişliklerini tamamen göz ardı eder.

(Not: bu özellik için Marcelo Glasberg’in assorted_layout_widgets adlı bir paketi mevcut. Bu paket içerisinde çocukları orijinal boyutlara göre orantılayan özel bir Row widgetı bulabilirsiniz)

Örnek 28

Scaffold(
body: Container(
color: blue,
child: Column(
children: [
Text('Hello!'),
Text('Goodbye!'),
]
)))

Scaffold ekran boyutunda olmaya zorlanır dolayısıyla tüm ekran Scaffold ile kaplanır.

Scaffold Container ‘a ekrandan büyük olmayacak şekilde istediği boyutta olabileceğini söyler.

Not: Bir widget çocuğuna belirli bir boyuttan küçük olabileceğini söylediğinde kastedilen şey çocuğa “gevşek” kısıtlama (loose constraints) getirilmesidir. Bu konuya tekrar geleceğiz.

Örnek 29

Scaffold(
body: SizedBox.expand(
child: Container(
color: blue,
child: Column(
children: [
Text('Hello!'),
Text('Goodbye!'),
],
))))

Scaffold ‘un çocuğunu Scaffold ile aynı boyutta olacak şekilde istediğimiz bir durumda, çocuğu SizedBox.expand ile sarmalayabiliriz.

Not: Eğer bir widget çocuğuna tam olarak belirli bir boyutta olmasını söylüyorsa, burada widget “sıkı” kısıtlama (tight constraints) yapıyordur.

Sıkı x Gevşek / Kısıtlamalar

Çoğu zaman sıkı veya gevşek (tight x loose constraints) kısıtlamalardan bahsedildiğini duyarız, bu yüzden bunların ne anlama geldiğini bilmekte fayda var.

Sıkı bir kısıtlama tek bir olasılık içerir, tam olarak belirli bir boyut. Başka bir deyişle, sıkı kısıtlama durumunda minimum genişlik maksimum genişliğe eşit, minimum yükseklik ise maksimum yüksekliğe eşittir.

Flutterda box.dart dosyasını açıp BoxConstraints yapıcısını incelediğinizde göreceğiniz şudur:

BoxConstraints.tight(Size size)
: minWidth = size.width,
maxWidth = size.width,
minHeight = size.height,
maxHeight = size.height;

Örnek 2'ye tekrar dönüp baktığınızda, kırmızı Container ‘ın ekranla aynı boyuta zorlandığını görürsünüz. Bunu yapan ekrandır, ve tabii ki bunu Container ‘a sıkı kısıtlama ileterek sağlar.

Öte yandan, gevşek bir kısıtlama ise maksimum genişlik/yüksekliği belirler, ama aynı zamanda, bunlardan istediği kadar küçük olabilme izni verir. Bu durumda, gevşek kısıtlamada minimum genişlik/yükseklik sıfır değerindedir.

BoxConstraints.loose(Size size)
: minWidth = 0.0,
maxWidth = size.width,
minHeight = 0.0,
maxHeight = size.height;

Örnek 3'e tekrar bakarsanız Center Container ‘a daha küçük olabilme ama en fazla da ekran kadar olma izni verir. Tabii ki Center bunu yaparken Container ‘a gevşek kısıtlamalar iletir. Neticede Center ‘ın amacı ekrandan aldığı (parent) sıkı kısıtlamaları, kendi çocuğu olan Container ‘a gevşek kısıtlama olarak dönüştürerek iletmektir.

Belirli widgetlar için layout kurallarını öğrenmek

Genel yerleşim kurallarını bilmek elbette gerekli ancak kendi başına yeterli değil.

Genel kurallar uygulanırken her bir widget’ın oldukça özgürlüğü vardır, bu nedenle sadece widget’ın adına bakarak nasıl davranacağını bilmenin bir yolu yoktur.

Tahminde bulunsanız da muhtemelen yanılacaksınız. Bir widget’ın dokümanlarını ve kaynak kodunu incelemeden tam olarak nasıl davranacağını tam olarak bilemezsiniz.

Yerleşimle ilgili kaynak kodlar genellikle karmaşıktır, bu yüzden ilgili dokümanları incelemek genellikle daha iyi bir yol. Yine de, eğer kaynak kodu incelemek isterseniz bunu kullandığınız IDE yardımıyla kolaylıkla bulabilirsiniz.

Örnek olarak:

  • Kodunuzdaki bir Column ‘a gelin ve kaynak koduna ilerleyin ( Ctrl-B IntelliJ ). Muhtemelen basic.dart dosyası açılacaktır. Column ise Flex ‘ten extend olduğundan Flex kısmına ilerleyin ( aynı dosya: basic.dart )
  • Şimdi createRenderObject metoduna kadar aşağı inin. Bu metodun bir RenderFlex döndürdüğünü göreceksiniz. Bu ise Column için karşılık gelen render-objesidir. RenderFlex için kaynak koduna ilerleyin ve flex.dart dosyasına gidin.
  • performLayout metodunu bulun. İşte Column için yerleşimi yapan metot budur.

--

--