Advanced Xamarin Forms Layout Tavsiyeleri

Merhaba Xamarin geliştiriciler,

Bu yazımda sizlere Xamarin Forms performans ayarlarından bahsedeceğim. Xamarin şirketinde çalışan profesyonellerinde dediği gibi Xamarin Forms un performansını etkileyen en can alıcı özellik Layout. Layout’un nasıl hazırlandığını bilmek bize uygularımızın Native olarak hazırlanmış uygulamaların performansını yakalama şansı verir.

Hemen hemen hepimiz biliriz ki Grid kullandığımızda colums ve rows ayarını “Auto” yapmayız. Peki neden? Sebebi gayet basit. Eğer auto column içindeki view boyutundaki en küçük değişiklik “MeasureInvalidated” eventinin calıştırılmasına sebep olur ki buda Layout sisteminin çalıştırılması anlamına gelir.

Xamarin Forms Layout Systemin iki kısımda inceleyebiliriz.

  • Invalidation kısmı
  • Layout kısmı

Invalidation Kısmı

Resimde de görüldüğü gibi layout ölçülerinin geçerliliğini yitirmesi child view’de başlıyor parent view’e gidiyor. Ve Layout çizimi parent view’de başlayıp child view’de sona eriyor.

Bu sistemi anlamak için birazda kod tarafına bakalım. Xamarin.Forms frameworkünü incelediğmizde Grid, Stacklayout, ve diğerlerinin VisualElement Class ından inherit edildiğini görürüz.

Uygulamamıza her Child view eklediğimizde Page veya Layout’a. Parent view eklenen child view’ün MeasureInvalidated eventine kendini subscribe eder. Bu şekilde child view’ün layout ölçüleri geçerliliğini yitirdiği anda gerekli olan yenileme işlemini başlatır.

view.MeasureInvalidated += OnChildMeasureInvalidated;

Şimdi bir grafik ile yakından bakalım.

Şimdi ise Invalidation kısmına baklalım.

Yukarıda da göründüğü gibi invalidation olayı aşağıdan yukarı doğru işlemektedir. Hiyerarşinin en altindaki child view den en uste giden bir event dalgalanmasindan bahsediyoruz burada ve bu olaylar sayfamizin ekrana cizdirilene kadar defalarca olabilmektedir.

Layout Kısmı

Layout kısmında iki durumdan bahsedebiliriz.

  1. Bir layout ilk defa gösterildiğinde (Page ilk defa gösterildiğinde veya sayfa ilk acildiginda)
  2. Invalidation kısmından sonra

Invalidation’dan sonra Parent view ilk olarak child view’ün Measure methodunu çağırır ve bu şekilde yukarıdan aşağı Measure Methodu çağrılır. Bu çoğu kez birden fazla olur. Bütün child view ler ölçüsü hazırlandıktan sonra Layout metodu çağrılarak layout oluşturma işlemi tamamlanır.

Aşağıdaki grafik ile resmin tamamına bakalım ve 2 kısmı bir arada görelim.

Aklınızdan geçeni duyar gibiyim tamam bunu anladım ama nasıl kullanacağım bu bilgimi.

Yukarıdaki şekildende anlaşılacağı üzere invalidate işlemini çok fazla yukarılara gitmeden durdurmak istiyoruz bu şekilde Layout işlemi çok fazla zaman almayacak ve daha kısa zamanda tamamlanacak. Şimdi bu öğrendiklerimizi kullanalım.

Bunun için Xamarin Forms Application oluşturdum. Sayfaya bir stacklayout ve birkaç tane Label koydum her Label 20 defa Text’ini değistirdim. Xamarin Forms frameworkünde de bu performansını ölçebilmek için değişiklik yaptım.

Beklentim Label’ın Text’ini değiştirince layout ölçüsününde değişmesi. Bu şekilde label layoutu olculeri degisecek ve Invalidate kısmı gerçekleşecek.

Uygulamayı çalıştırdıktan sonra gördüm ki, Label’ın her değişiminde LayoutChildIntoBoundingRegion  243 defa çağırılıyor. Buda gösteriyor ki her text değişimi sadece Label’ın layout’unu değil tam sayfa layout’un yenilenmesine sebep oluyor. Buda sayfanın tamamen ekrana çizdirilmesi demek oluyor.

Aynı işlemi Grid kullanarak deneyelim. Fakat Row Height ayarini Auto olarak ayarlayalım.

Sonucun değişmediğini ve bütün sayfanın sıfırdan çizildiğini görüyoruz.

Tekrar Grid ile deneme yapalım bu sefer Auto yerine * seçelim.

Sonuç harika LayoutChildIntoBoundingRegion 6 kez çağırılmış. Bu demek oluyor ki sadece ilk gösterimde sayfa tamamen hesaplanıp çizilmiş ondan sonra herhangi bir değişiklik olmamış.

Buraya kadar herhalde biraz yorulmuşsunuzdur. Şimdi son örneğimizide görüp bu yazıyı tamamlayacağım. Bu örnekte Gridimizin içine ölçüleri dinamik olarak değişen Box koyacağım. Bakalım neler olacak?

BoxView’ün Width’ini değiştirebilmem için HorizontalOptions Start olarak ayarladım. Sonucu merak ettiniz acaba nasıl olacak? Ama başa geri döndük.  243 kez full layout işlemi olmakta. Bunu sebebi HorizontalOptions’ı değiştirmekti? Peki bunu nasıl düzeltebiliriz?

Çözüm gayet basit BoxView’ü ContentView içine koymak. Bakalım bu işlemi yaptıktan sonra sonu ne olacak?

Birde sonuca bakalım.

Ve bu işlemde de başarlı olduk. Buraya kadar iyi iş çıkardık ve işimize yarayacak seyler oğrendik.

Özetlemek gerekirse:

  • Stacklayout’a ne eklerseniz ekleyin sayfanızın tamamı hesaplanıp çizilecektir.
  • Eğer Gridin herhangi bir row veya column static veya yıldız * ve layoutOptions Fill olarak ayarlanmışsa onun içindeki view ölçüsü değisse dahi bir üstünü invalidate etmez ve sayfamızın tamamen çizilme işinden korunmuş oluruz.
  • Eğer Gridin içinde ölçüsü dinamik olarak değişen bir view kullanacaksak bunu layout’u tamamen sabitlenmiş başka bir view’ün içine koymamız gerekir. BoxView örneğinde görüldüğü gibi.

Buraya kadar Layout olayını biraz anlatmaya çalıştım. Sizlere daha fazla bilgi edinmek istiyorsanız Jason Smith Evolve sunumunu izlemenizi tavsiye ederim.

Bir başka yazıda görüşmek üzere 🙂

Ümit Nuri Aydın

1 Yorum

You can post comments in this post.


  • Xamarin.Android geliştiricisiym.Forms’a yeni başladım.Çok güzel bir makale olmuş teşekkür ediyorum.

    ali ihsan 5 sene ago Reply


Yorum Gönder