Aracılığıyla paylaş


uygulamasında Özel Düzen oluşturma Xamarin.Forms

Xamarin.Forms beş düzen sınıfı tanımlar: StackLayout, AbsoluteLayout, RelativeLayout, Grid ve FlexLayout ve her biri alt öğelerini farklı bir şekilde düzenler. Ancak, bazen sayfa içeriğini tarafından Xamarin.Formssağlanmayan bir düzen kullanarak düzenlemek gerekir. Bu makalede özel bir düzen sınıfının nasıl yazıldığını açıklar ve alt öğelerini sayfada yatay olarak yerleştiren ve ardından sonraki alt öğelerin görünümünü ek satırlara kaydıran, yönlendirmeye duyarlı wrapLayout sınıfını gösterir.

içinde Xamarin.Forms, tüm düzen sınıfları sınıfından Layout<T> türetilir ve genel türü View ile türetilen türlerini kısıtlar. Buna karşılık, Layout<T> sınıf, alt öğeleri konumlandırmak ve boyutlandırmak için mekanizma sağlayan sınıfından türetilir Layout .

Her görsel öğesi, istenen boyut olarak bilinen kendi tercih edilen boyutunu belirlemekle sorumludur. Page, Layoutve Layout<View> türetilmiş türler, kendilerine göre çocuklarının veya çocuklarının konumunu ve boyutunu belirlemekle sorumludur. Bu nedenle, düzen, üst öğe alt öğelerinin boyutunun ne olması gerektiğini belirlediği ancak çocuğun istenen boyutunu barındırmaya çalışacağı bir üst-alt ilişki içerir.

Özel bir düzen oluşturmak için düzeni ve geçersizleştirme döngülerini ayrıntılı bir şekilde anlamak Xamarin.Forms gerekir. Bu döngüler artık ele alınacaktır.

Düzen

Düzen, görsel ağacının en üstünde bir sayfayla başlar ve sayfadaki tüm görsel öğeleri kapsayacak şekilde görsel ağacının tüm dallarında ilerler. Diğer öğelerin ebeveyni olan öğeler, çocuklarının kendilerine göre boyutlandırılmasından ve konumlandırılmasından sorumludur.

sınıfıVisualElement, düzen işlemleri için bir öğeyi ölçen bir yöntem ve öğenin içinde işlenecek dikdörtgen alanı belirten bir Layout yöntem tanımlarMeasure. Bir uygulama başlatıldığında ve ilk sayfa görüntülendiğinde, ilk çağrılardan ve ardından çağrılardan Measure oluşan bir düzen döngüsü nesne üzerinde Page başlar:Layout

  1. Düzen döngüsü sırasında, her üst öğe alt öğelerinde yöntemini çağırmaktan Measure sorumludur.
  2. Alt öğeler ölçüldükten sonra, her üst öğe alt öğelerinde yöntemini çağırmaktan Layout sorumludur.

Bu döngü, sayfadaki her görsel öğenin ve Layout yöntemlerine Measure çağrılar almasını sağlar. İşlem aşağıdaki diyagramda gösterilmiştir:

Xamarin.Forms Düzen Döngüsü

Not

Düzeni etkileyecek bir değişiklik olduğunda, düzen döngülerinin görsel ağacının bir alt kümesinde de gerçekleşebileceğini unutmayın. Buna, içinde gibi StackLayoutbir koleksiyona eklenen veya kaldırılan öğeler, öğenin özelliğinde IsVisible yapılan bir değişiklik veya öğenin boyutundaki bir değişiklik dahildir.

veya Children özelliği olan her Xamarin.Forms sınıfın Content geçersiz kılınabilir LayoutChildren bir yöntemi vardır. öğesinden Layout<View> türetilen özel düzen sınıfları bu yöntemi geçersiz kılmalı ve istenen özel düzeni sağlamak için ve Layout yöntemlerinin öğenin tüm alt öğelerinde çağrıldığından emin olmalıdırMeasure.

Ayrıca, öğesinden Layout türetilen veya Layout<View> yöntemini geçersiz kılması OnMeasure gereken her sınıf, bir düzen sınıfının alt öğelerinin yöntemlerine Measure çağrılar yaparak olması gereken boyutu belirlediği yöntemdir.

Not

Öğeler boyutlarını kısıtlamalara göre belirler ve bu da öğenin üst öğesi içindeki bir öğe için ne kadar alan olduğunu gösterir. ve OnMeasure yöntemlerine Measure geçirilen kısıtlamalar 0 Double.PositiveInfinityile arasında değişebilir. Bir öğe, sonsuz olmayan bağımsız değişkenlerle yöntemine Measure bir çağrı aldığında kısıtlanmış veya tamamen kısıtlanmış olur. Öğe belirli bir boyuta kısıtlanır. Bir öğe, yöntemine Measure en az bir bağımsız değişkene eşit Double.PositiveInfinity bir çağrı aldığında kısıtlanmamış veya kısmen kısıtlanmış olur; sonsuz kısıtlama otomatikleştirmeyi gösterir olarak düşünülebilir.

Örneğin

Geçersizleştirme, sayfadaki bir öğedeki değişikliğin yeni bir düzen döngüsünü tetiklediği işlemdir. Öğeler artık doğru boyuta veya konuma sahip olmadığında geçersiz kabul edilir. Örneğin, bir Button değişikliğin FontSizeButton özelliği artık doğru boyuta sahip olmayacağından geçersiz olduğu söylenir. Yeniden boyutlandırma, Button sayfanın geri kalanında düzendeki değişikliklerin dalgalı bir etkisine sahip olabilir.

Genellikle öğenin bir özelliği öğenin yeni boyutuna InvalidateMeasure neden olabilecek değiştiğinde, öğeler yöntemini çağırarak kendilerini geçersiz hale getirir. Bu yöntem, öğenin üst öğesinin MeasureInvalidated yeni bir düzen döngüsünü tetikleyecek şekilde işlediği olayı tetikler.

sınıfı, Layout özelliğine veya Children koleksiyonuna MeasureInvalidatedContent eklenen her alt öğede olay için bir işleyici ayarlar ve alt öğe kaldırıldığında işleyiciyi ayırır. Bu nedenle, görsel ağaçta alt öğeleri olan her öğe, alt öğelerinden birinin boyutu değiştiğinde uyarı alır. Aşağıdaki diyagramda, görsel ağaçtaki bir öğenin boyutundaki bir değişikliğin ağacı dalgalayan değişikliklere nasıl neden olabileceği gösterilmektedir:

Görsel Ağaçta GeçersizLeştirme

Ancak sınıf, Layout bir çocuğun boyutundaki değişikliğin sayfa düzeni üzerindeki etkisini kısıtlamaya çalışır. Düzen boyutu kısıtlanmışsa, alt boyut değişikliği görsel ağaçtaki üst düzenden daha yüksek bir şeyi etkilemez. Ancak, genellikle düzenin boyutundaki bir değişiklik, düzenin alt öğelerini nasıl düzenleyeceğini etkiler. Bu nedenle, düzenin boyutundaki herhangi bir değişiklik düzen için bir düzen döngüsü başlatır ve düzen ve LayoutChildren yöntemlerine OnMeasure çağrılar alır.

sınıfı, Layout yöntemine InvalidateMeasure benzer bir amaca sahip olan bir InvalidateLayout yöntemi de tanımlar. Düzenin InvalidateLayout alt öğelerini nasıl konumlandırdığını ve boyutlandırdığını etkileyen bir değişiklik yapıldığında yöntemi çağrılmalıdır. Örneğin, Layout bir alt öğe bir düzene eklendiğinde veya bir düzenden kaldırıldığında sınıfı yöntemini çağırır InvalidateLayout .

düzenin InvalidateLayout alt öğelerinin yöntemlerinin yinelenen çağrılarını Measure en aza indirmek için bir önbellek uygulamak için geçersiz kılınabilir. yöntemi geçersiz kılındığında InvalidateLayout , alt öğeler düzene eklendiğinde veya düzenden kaldırıldığında bir bildirim sağlanır. Benzer şekilde, düzenin OnChildMeasureInvalidated alt öğelerinden birinin boyutu değiştiğinde bildirim sağlamak için yöntemi geçersiz kılınabilir. Her iki yöntem geçersiz kılması için özel bir düzen önbelleği temizleyerek yanıt vermelidir. Daha fazla bilgi için bkz . Düzen Verilerini Hesaplama ve Önbelleğe Alma.

Özel Düzen Oluşturma

Özel düzen oluşturma işlemi aşağıdaki gibidir:

  1. sınıfından türetilen Layout<View> bir sınıf oluşturun. Daha fazla bilgi için bkz . WrapLayout oluşturma.

  2. [isteğe bağlı] Düzen sınıfında ayarlanması gereken parametreler için bağlanabilir özellikler tarafından yedeklenen özellikler ekleyin. Daha fazla bilgi için bkz . Bağlanabilir Özellikler Tarafından Yedeklenen Özellikler Ekleme.

  3. OnMeasure Yöntemi düzendeki tüm alt öğelerde çağırmak Measure ve düzen için istenen boyutu döndürmek için yöntemini geçersiz kılın. Daha fazla bilgi için bkz . OnMeasure Yöntemini Geçersiz Kılma.

  4. Yöntemi, düzenin LayoutChildrenLayout tüm alt öğelerinde çağırmak için geçersiz kılın. Bir düzendeki her alt öğede yönteminin çağrılmaması Layout , çocuğun hiçbir zaman doğru boyut veya konum almamasına neden olur ve bu nedenle çocuk sayfada görünmez. Daha fazla bilgi için bkz . LayoutChildren Yöntemini Geçersiz Kılma.

    Not

    ve geçersiz kılmalarında OnMeasure alt öğeleri numaralandırırken, özelliği olarak falseayarlanmış olan IsVisible tüm alt öğeleri atlayın.LayoutChildren Bu, özel düzenin görünmez çocuklar için alan bırakmamasını sağlar.

  5. [isteğe bağlı] Alt öğeler düzene eklendiğinde veya düzenden kaldırıldığında bildirilecek yöntemi geçersiz kılın InvalidateLayout . Daha fazla bilgi için bkz . InvalidateLayout Yöntemini Geçersiz Kılma.

  6. [isteğe bağlı] Düzenin OnChildMeasureInvalidated alt öğelerinden birinin boyutu değiştiğinde bildirim almak için yöntemini geçersiz kılın. Daha fazla bilgi için bkz . OnChildMeasureInvalidated Yöntemini Geçersiz Kılma.

Not

Düzenin OnMeasure boyutu alt öğeleri yerine üst öğe tarafından yönetiliyorsa geçersiz kılmanın çağrılmayacağını unutmayın. Ancak, kısıtlamalardan biri veya her ikisi de sonsuzsa veya düzen sınıfı varsayılan HorizontalOptions olmayan veya VerticalOptions özellik değerlerine sahipse geçersiz kılma çağrılır. Bu nedenle geçersiz kılma, LayoutChildren yöntem çağrısı sırasında OnMeasure elde edilen alt boyutları kullanamaz. Bunun yerine, LayoutChildren yöntemini çağırmadan önce düzenin alt öğelerinde yöntemini çağırması MeasureLayout gerekir. Alternatif olarak, geçersiz kılmada daha sonra Measure çağrılmasını LayoutChildren önlemek için geçersiz kılmada OnMeasure elde edilen çocukların boyutu önbelleğe alınabilir, ancak düzen sınıfının boyutların yeniden ne zaman alınması gerektiğini bilmesi gerekir. Daha fazla bilgi için bkz . Düzen Verilerini Hesaplama ve Önbelleğe Alma.

Düzen sınıfı daha sonra bir öğesine Pageeklenerek ve düzene alt öğeler eklenerek kullanılabilir. Daha fazla bilgi için bkz . WrapLayout kullanma.

WrapLayout oluşturma

Örnek uygulama, alt öğelerini sayfada yatay olarak yerleştiren ve ardından sonraki alt öğelerin görünümünü ek satırlara kaydıran, yönlendirmeye duyarlı WrapLayout bir sınıf gösterir.

sınıfıWrapLayout, alt öğelerin en büyük boyutuna göre her alt öğe için hücre boyutu olarak bilinen aynı miktarda alan ayırır. Hücre boyutundan küçük çocuklar ve VerticalOptions özellik değerlerine HorizontalOptions göre hücre içinde konumlandırılabilir.

Sınıf WrapLayout tanımı aşağıdaki kod örneğinde gösterilmiştir:

public class WrapLayout : Layout<View>
{
  Dictionary<Size, LayoutData> layoutDataCache = new Dictionary<Size, LayoutData>();
  ...
}

Düzen Verilerini Hesaplama ve Önbelleğe Alma

Yapı, LayoutData bir alt öğe koleksiyonu hakkındaki verileri bir dizi özellikte depolar:

  • VisibleChildCount – düzende görünen alt öğe sayısı.
  • CellSize – düzenin boyutuna göre ayarlanmış tüm alt öğeleri en büyük boyut.
  • Rows – satır sayısı.
  • Columns – sütun sayısı.

Alanı layoutDataCache , birden çok LayoutData değeri depolamak için kullanılır. Uygulama başlatıldığında, geçerli yönlendirme için sözlükte iki LayoutData nesne önbelleğe layoutDataCache alınır: biri geçersiz kılmaya yönelik kısıtlama bağımsız değişkenleri OnMeasure ve geçersiz kılmaya yönelik width ve height bağımsız değişkenleri için LayoutChildren . Cihazı yatay yönlendirmeye döndürürken, OnMeasure geçersiz kılma ve geçersiz kılma yeniden çağrılır ve LayoutChildren bu da sözlükte başka iki LayoutData nesnenin önbelleğe alınmasına neden olur. Ancak, cihazı dikey yönlendirmeye döndürürken, gerekli veriler zaten olduğundan layoutDataCache başka hesaplama yapılması gerekmez.

Aşağıdaki kod örneği, belirli bir boyuta GetLayoutData göre yapılandırılmış özellikleri LayoutData hesaplayan yöntemini gösterir:

LayoutData GetLayoutData(double width, double height)
{
  Size size = new Size(width, height);

  // Check if cached information is available.
  if (layoutDataCache.ContainsKey(size))
  {
    return layoutDataCache[size];
  }

  int visibleChildCount = 0;
  Size maxChildSize = new Size();
  int rows = 0;
  int columns = 0;
  LayoutData layoutData = new LayoutData();

  // Enumerate through all the children.
  foreach (View child in Children)
  {
    // Skip invisible children.
    if (!child.IsVisible)
      continue;

    // Count the visible children.
    visibleChildCount++;

    // Get the child's requested size.
    SizeRequest childSizeRequest = child.Measure(Double.PositiveInfinity, Double.PositiveInfinity);

    // Accumulate the maximum child size.
    maxChildSize.Width = Math.Max(maxChildSize.Width, childSizeRequest.Request.Width);
    maxChildSize.Height = Math.Max(maxChildSize.Height, childSizeRequest.Request.Height);
  }

  if (visibleChildCount != 0)
  {
    // Calculate the number of rows and columns.
    if (Double.IsPositiveInfinity(width))
    {
      columns = visibleChildCount;
      rows = 1;
    }
    else
    {
      columns = (int)((width + ColumnSpacing) / (maxChildSize.Width + ColumnSpacing));
      columns = Math.Max(1, columns);
      rows = (visibleChildCount + columns - 1) / columns;
    }

    // Now maximize the cell size based on the layout size.
    Size cellSize = new Size();

    if (Double.IsPositiveInfinity(width))
      cellSize.Width = maxChildSize.Width;
    else
      cellSize.Width = (width - ColumnSpacing * (columns - 1)) / columns;

    if (Double.IsPositiveInfinity(height))
      cellSize.Height = maxChildSize.Height;
    else
      cellSize.Height = (height - RowSpacing * (rows - 1)) / rows;

    layoutData = new LayoutData(visibleChildCount, cellSize, rows, columns);
  }

  layoutDataCache.Add(size, layoutData);
  return layoutData;
}

GetLayoutData yöntemi aşağıdaki işlemleri gerçekleştirir:

  • Hesaplanmış LayoutData bir değerin önbellekte olup olmadığını belirler ve varsa döndürür.
  • Aksi takdirde, tüm alt öğeleri numaralandırır, sonsuz genişlik ve boya sahip her alt öğede yöntemini çağırır Measure ve en büyük alt boyutu belirler.
  • En az bir görünür alt öğe olması koşuluyla, gerekli satır ve sütun sayısını hesaplar ve ardından alt öğeler için boyutlarına WrapLayoutgöre bir hücre boyutu hesaplar. Hücre boyutunun genellikle en büyük çocuk boyutundan biraz daha geniş olduğunu, ancak en geniş çocuk için yeterince geniş değilse veya en uzun çocuk için yeterince uzun değilse WrapLayout daha küçük olabileceğini unutmayın.
  • Yeni LayoutData değeri önbellekte depolar.

Bağlanabilir Özellikler Tarafından Yedeklenen Özellikler Ekleme

WrapLayout sınıfı, değerleri düzendeki satır ve sütunları ayırmak için kullanılan ve bağlanabilir özellikler tarafından yedeklenen ve özelliklerini tanımlar ColumnSpacingRowSpacing. Bağlanabilir özellikler aşağıdaki kod örneğinde gösterilmiştir:

public static readonly BindableProperty ColumnSpacingProperty = BindableProperty.Create(
  "ColumnSpacing",
  typeof(double),
  typeof(WrapLayout),
  5.0,
  propertyChanged: (bindable, oldvalue, newvalue) =>
  {
    ((WrapLayout)bindable).InvalidateLayout();
  });

public static readonly BindableProperty RowSpacingProperty = BindableProperty.Create(
  "RowSpacing",
  typeof(double),
  typeof(WrapLayout),
  5.0,
  propertyChanged: (bindable, oldvalue, newvalue) =>
  {
    ((WrapLayout)bindable).InvalidateLayout();
  });

Her bağlanabilir özelliğin özellik tarafından değiştirilen işleyicisi, üzerinde yeni bir düzen geçişi tetikleyen yöntem geçersiz kılmasını WrapLayoutçağırırInvalidateLayout. Daha fazla bilgi için bkz . InvalidateLayout Yöntemini Geçersiz Kılma ve OnChildMeasureInvalidated Yöntemini Geçersiz Kılma.

OnMeasure Yöntemini Geçersiz Kılma

Geçersiz OnMeasure kılma aşağıdaki kod örneğinde gösterilmiştir:

protected override SizeRequest OnMeasure(double widthConstraint, double heightConstraint)
{
  LayoutData layoutData = GetLayoutData(widthConstraint, heightConstraint);
  if (layoutData.VisibleChildCount == 0)
  {
    return new SizeRequest();
  }

  Size totalSize = new Size(layoutData.CellSize.Width * layoutData.Columns + ColumnSpacing * (layoutData.Columns - 1),
                layoutData.CellSize.Height * layoutData.Rows + RowSpacing * (layoutData.Rows - 1));
  return new SizeRequest(totalSize);
}

Geçersiz kılma yöntemini çağırır GetLayoutData ve döndürülen verilerden bir SizeRequest nesne oluştururken ve ColumnSpacing özellik değerlerini de dikkate RowSpacing alır. Yöntemi hakkında GetLayoutData daha fazla bilgi için bkz . Hesaplama ve Önbellek Düzeni Verileri.

Önemli

Measure ve OnMeasure yöntemleri, özelliği olarak ayarlanmış Double.PositiveInfinitybir SizeRequest değer döndürerek hiçbir zaman sonsuz boyut istememelidir. Ancak, için OnMeasure kısıtlama bağımsız değişkenlerinden en az biri olabilir Double.PositiveInfinity.

LayoutChildren Yöntemini Geçersiz Kılma

Geçersiz LayoutChildren kılma aşağıdaki kod örneğinde gösterilmiştir:

protected override void LayoutChildren(double x, double y, double width, double height)
{
  LayoutData layoutData = GetLayoutData(width, height);

  if (layoutData.VisibleChildCount == 0)
  {
    return;
  }

  double xChild = x;
  double yChild = y;
  int row = 0;
  int column = 0;

  foreach (View child in Children)
  {
    if (!child.IsVisible)
    {
      continue;
    }

    LayoutChildIntoBoundingRegion(child, new Rectangle(new Point(xChild, yChild), layoutData.CellSize));
    if (++column == layoutData.Columns)
    {
      column = 0;
      row++;
      xChild = x;
      yChild += RowSpacing + layoutData.CellSize.Height;
    }
    else
    {
      xChild += ColumnSpacing + layoutData.CellSize.Width;
    }
  }
}

Geçersiz kılma yöntemine GetLayoutData yapılan bir çağrıyla başlar ve sonra tüm alt öğeleri her alt öğe hücresinde boyutlandırmak ve konumlandırmak için numaralandırır. Bu, bir alt öğeyi ve VerticalOptions özellik değerlerine LayoutChildIntoBoundingRegion göre HorizontalOptions dikdörtgen içinde konumlandırmak için kullanılan yöntemini çağırarak elde edilir. Bu, çocuğun Layout yöntemine çağrı yapmaya eşdeğerdir.

Not

yöntemine geçirilen dikdörtgenin LayoutChildIntoBoundingRegion , çocuğun bulunabileceği alanın tamamını içerdiğini unutmayın.

Yöntemi hakkında GetLayoutData daha fazla bilgi için bkz . Hesaplama ve Önbellek Düzeni Verileri.

InvalidateLayout Yöntemini Geçersiz Kılma

Geçersiz InvalidateLayout kılma, aşağıdaki kod örneğinde gösterildiği gibi alt öğeler düzene eklendiğinde veya düzenden kaldırıldığında ya da özelliklerden WrapLayout biri değeri değiştirdiğinde çağrılır:

protected override void InvalidateLayout()
{
  base.InvalidateLayout();
  layoutInfoCache.Clear();
}

Geçersiz kılma, düzeni geçersiz kılar ve önbelleğe alınan tüm düzen bilgilerini atar.

Not

Bir düzene bir alt öğe eklendiğinde veya bir düzenden kaldırıldığında sınıfın yöntemini çağırmasını durdurmak Layout için ve ShouldInvalidateOnChildRemoved yöntemlerini geçersiz kılın ShouldInvalidateOnChildAdded ve döndürürfalse.InvalidateLayout Düzen sınıfı daha sonra alt öğeler eklendiğinde veya kaldırıldığında özel bir işlem uygulayabilir.

OnChildMeasureInvalidated Yöntemini Geçersiz Kılma

Düzenin OnChildMeasureInvalidated alt öğelerinden birinin boyutu değiştiğinde geçersiz kılma çağrılır ve aşağıdaki kod örneğinde gösterilir:

protected override void OnChildMeasureInvalidated()
{
  base.OnChildMeasureInvalidated();
  layoutInfoCache.Clear();
}

Geçersiz kılma alt düzeni geçersiz kılar ve önbelleğe alınan tüm düzen bilgilerini atar.

WrapLayout kullanma

Sınıfı WrapLayout , aşağıdaki XAML kod örneğinde gösterildiği gibi türetilmiş bir Page türe yerleştirilerek kullanılabilir:

<ContentPage ... xmlns:local="clr-namespace:ImageWrapLayout">
    <ScrollView Margin="0,20,0,20">
        <local:WrapLayout x:Name="wrapLayout" />
    </ScrollView>
</ContentPage>

Eşdeğer C# kodu aşağıda gösterilmiştir:

public class ImageWrapLayoutPageCS : ContentPage
{
  WrapLayout wrapLayout;

  public ImageWrapLayoutPageCS()
  {
    wrapLayout = new WrapLayout();

    Content = new ScrollView
    {
      Margin = new Thickness(0, 20, 0, 20),
      Content = wrapLayout
    };
  }
  ...
}

Daha sonra alt öğelere gerektiği gibi eklenebilir WrapLayout . Aşağıdaki kod örneği öğesine eklenen WrapLayoutöğeleri gösterirImage:

protected override async void OnAppearing()
{
    base.OnAppearing();

    var images = await GetImageListAsync();
    if (images != null)
    {
        foreach (var photo in images.Photos)
        {
            var image = new Image
            {
                Source = ImageSource.FromUri(new Uri(photo))
            };
            wrapLayout.Children.Add(image);
        }
    }
}

async Task<ImageList> GetImageListAsync()
{
    try
    {
        string requestUri = "https://raw.githubusercontent.com/xamarin/docs-archive/master/Images/stock/small/stock.json";
        string result = await _client.GetStringAsync(requestUri);
        return JsonConvert.DeserializeObject<ImageList>(result);
    }
    catch (Exception ex)
    {
        Debug.WriteLine($"\tERROR: {ex.Message}");
    }

    return null;
}

öğesini içeren sayfa göründüğünde WrapLayout , örnek uygulama fotoğraf listesini içeren uzak bir JSON dosyasına zaman uyumsuz olarak erişir, her fotoğraf için bir Image öğe oluşturur ve bunu WrapLayoutöğesine ekler. Bu, aşağıdaki ekran görüntülerinde gösterilen görünüme neden olur:

Örnek Uygulama Dikey Ekran Görüntüleri

Aşağıdaki ekran görüntüleri, yatay yönlendirmeye döndürüldükten sonrasını gösterir WrapLayout :

Örnek iOS Uygulama Yatay Ekran GörüntüsüÖrnek Android Uygulaması Yatay Ekran GörüntüsüÖrnek UWP Uygulaması Yatay Ekran Görüntüsü

Her satırdaki sütun sayısı fotoğraf boyutuna, ekran genişliğine ve cihazdan bağımsız birim başına piksel sayısına bağlıdır. Image Öğeler fotoğrafları zaman uyumsuz olarak yükler ve bu nedenle WrapLayout her Image öğe yüklenen fotoğrafa göre yeni bir boyut aldığından sınıfı yöntemine sık sık çağrılar LayoutChildren alır.