Xamarin.Form's LayoutOptions, özellikle Fill and Expand arasındaki fark nedir?


170

Xamarin.Forms'da her Viewiki özellik HorizontalOptionsve vardır VerticalOptions. Her ikisi de türdedir LayoutOptionsve aşağıdaki değerlerden birine sahip olabilir:

  • LayoutOptions.Start
  • LayoutOptions.Center
  • LayoutOptions.End
  • LayoutOptions.Fill
  • LayoutOptions.StartAndExpand
  • LayoutOptions.CenterAndExpand
  • LayoutOptions.EndAndExpand
  • LayoutOptions.FillAndExpand

Görünüşe göre üst görünümdeki görünümün hizalamasını kontrol eder. Ancak her bir seçeneğin davranışı tam olarak nasıl? Ve Fillson ek ile arasındaki fark Expandnedir?

Yanıtlar:


335

Kısa cevap

Start, Center, EndVe Fillgörünümün tanımlamak kendi alanı içinde hizalama .

Expandmevcutsa daha fazla yer kaplayıp kaplamadığını tanımlar .

teori

Yapı LayoutOptionsiki farklı davranışı kontrol eder:

  1. Hizalama: Görünüm, üst görünümde nasıl hizalanır?

    • Start: Dikey hizalama için görünüm en üste taşınır. Yatay hizalama için bu genellikle sol taraftır. (Ancak, sağdan sola dil ayarına sahip cihazlarda bunun başka bir yol olduğunu, yani sağa hizalandığını unutmayın.)
    • Center: Görünüm ortalanmıştır.
    • End: Genellikle görünüm aşağı veya sağa hizalanır. (Sağdan sola yazılan dillerde, elbette, sola hizalı.)
    • Fill: Bu hizalama biraz farklıdır. Görünüm, üst görünümün tam boyutuna uzanır.

    Bununla birlikte, ebeveyn çocuklarından daha büyük değilse, bu hizalamalar arasında herhangi bir fark görmezsiniz. Hizalama, yalnızca ek alan bulunan üst görünümler için önemlidir.

  2. Genişleme: Eleman varsa daha fazla yer kaplar mı?

    • Sonek Expand: Üst görünüm, tüm çocuklarının birleştirilmiş boyutundan daha büyükse, yani ek alan varsa, bu alan, bu sonekle alt görünümler arasında oranlanır. Bu çocuklar alanlarını "işgal edecek", ancak mutlaka "doldurmayacak". Aşağıdaki örnekte bu davranışa bir göz atacağız.
    • Sonek yok: Son Expandeki olmayan çocuklar , daha fazla yer olsa bile ek alan elde etmez.

    Yine, ebeveyn görüşü çocuklarından daha büyük değilse, genişleme soneki de herhangi bir fark yaratmaz.

Misal

Sekiz düzen seçeneğinin tümü arasındaki farkı görmek için aşağıdaki örneğe bakalım.

Uygulama StackLayout, her biri dikey düzen seçeneğiyle etiketlenmiş sekiz iç içe beyaz düğmeli koyu gri içerir . Düğmelerden birine tıklandığında, dikey düzen seçeneğini yığın düzenine atar. Bu şekilde, görünümlerin her ikisi de farklı düzen seçeneği ile ebeveynlerle etkileşimini kolayca test edebiliriz.

(Son birkaç kod satırı ek sarı kutular ekler. Biraz sonra buna geri döneceğiz.)

public static class App
{
    static readonly StackLayout stackLayout = new StackLayout {
        BackgroundColor = Color.Gray,
        VerticalOptions = LayoutOptions.Start,
        Spacing = 2,
        Padding = 2,
    };

    public static Page GetMainPage()
    {
        AddButton("Start", LayoutOptions.Start);
        AddButton("Center", LayoutOptions.Center);
        AddButton("End", LayoutOptions.End);
        AddButton("Fill", LayoutOptions.Fill);
        AddButton("StartAndExpand", LayoutOptions.StartAndExpand);
        AddButton("CenterAndExpand", LayoutOptions.CenterAndExpand);
        AddButton("EndAndExpand", LayoutOptions.EndAndExpand);
        AddButton("FillAndExpand", LayoutOptions.FillAndExpand);

        return new NavigationPage(new ContentPage {
            Content = stackLayout,
        });
    }

    static void AddButton(string text, LayoutOptions verticalOptions)
    {
        stackLayout.Children.Add(new Button {
            Text = text,
            BackgroundColor = Color.White,
            VerticalOptions = verticalOptions,
            HeightRequest = 20,
            Command = new Command(() => {
                stackLayout.VerticalOptions = verticalOptions;
                (stackLayout.ParentView as Page).Title = "StackLayout: " + text;
            }),
        });
        stackLayout.Children.Add(new BoxView {
            HeightRequest = 1,
            Color = Color.Yellow,
        });
    }
}

Aşağıdaki ekran görüntüleri, sekiz düğmenin her birine tıklandığında sonucu gösterir. Aşağıdaki gözlemleri yapıyoruz:

  • Üst stackLayoutöğe sıkı olduğu sürece ( Fillsayfa değil ), her birinin dikey düzen seçeneği Buttongöz ardı edilebilir.
  • Dikey mizanpaj seçeneği yalnızca stackLayout, daha büyükse (örn. FillHizalama yoluyla ) ve ayrı düğmelerin Expandsoneki varsa önemlidir .
  • Ek alan, Expandsonek içeren tüm düğmeler arasında açıkça orantılıdır . Bunu daha net görmek için, her iki komşu düğmeye arasına sarı yatay çizgiler ekledik.
  • İstenilen yüksekliklerinden daha fazla alana sahip düğmeler mutlaka "doldurmaz". Bu durumda, fiili davranış hizalanmalarıyla kontrol edilir. Örneğin, boşluklarının üstüne, ortasına veya düğmesine hizalanır veya tamamen doldururlar.
  • Tüm düğmeler mizanpajın tüm genişliği boyunca uzanır, çünkü yalnızca VerticalOptions.

Ekran görüntüleri

Burada karşılık gelen yüksek çözünürlüklü ekran görüntülerini bulabilirsiniz.


6
görüntü [[midfing]] gibi görünüyor, lol. Şaka yapıyorum gerçekten yardımcı oldu
Joy Rex

1
@JoyRex: Belki de bu sürüm biraz daha kafa karıştırıcı. ;)
Falko

2
Yukarıdaki çıktı ile karıştırdım. start & startAndExpand her ikisi de aynı çıktıdır. Bunlar arasındaki fark nedir? mümkünse açıklama yapabilir misiniz ..
Ranjith Kumar

1
FillAndExpandİstediğiniz zaman,% 99 zaman
Stephane Delcroix

1
@RanjithKumar Onlar aynı. Bu StackLayout daha sonra FillAndExpand bir fark yaratabilir başka bir üst iç içe oldu - bu dahilinde artıracağı onun ebeveyn.
Miha Markic

16

Xamarin.Forms geçerli sürümünde bir hata biraz var; belki bir süredir oradaydı.

CenterAndExpand genellikle genişlemez ve etrafta çalışmak kafa karıştırıcı olabilir.

Örneğin bir varsa StackLayoutiçin set CenterAndExpandiçin o zaman o da set içinde bir etiket koymak, CenterAndExpandsen tam genişliği bir etiket beklenebilir StackLayout. Hayır! Genişlemez. Yuvalanmış Label nesnesinin tam genişliğine genişlemesi StackLayoutiçin " FillAndExpand" ayarını yapmanız ve StackLayoutardından Etikete kendisini bir nesne olarak değil, metni ortalamasını söylemesi gerekir HorizontalTextAlignment="Center". Deneyimlerime göre, FillAndExpandeğer gerçekten sığacak şekilde genişlediğinden emin olmak istiyorsanız hem ebeveynin hem de iç içe geçmiş çocuğun ayarlanması gerekir .

        <StackLayout HorizontalOptions="FillAndExpand"
                     Orientation="Vertical"
                     WidthRequest="300">
            <Label BackgroundColor="{StaticResource TileAlerts}"
                   HorizontalOptions="FillAndExpand"
                   Style="{StaticResource LabelStyleReversedLrg}"
                   HorizontalTextAlignment="Center"
                   Text="Alerts" />

3
"... StackLayout'un tam genişliği olan bir etiket beklersiniz." Bu varsayım yanlış. Expandyalnızca StackLayout'un çocukları için kullanılır. Bu nedenle, StackLayout'unuz kökse veya başka bir StackLayout'ta değilse, Expandhiçbir etkisi yoktur. Bunun yerine, Dolgu dışında herhangi bir seçenek boyutlandırma için gördüğünüz gibi bir "içeriği kaydır" işlevi görür.
therealjohn

Ayrıca, genişletme yalnızca StackLayout öğesiyle aynı yönlendirmeye sahip LayoutOptions için çalışır. Bu durumda, düzen "Dikey" dir, ancak söz konusu seçenekler Yatay'dır (karşıtlar).
therealjohn

"AndExpand" terimi belirsiz. "Mümkün olduğunca genişlet" veya "yalnızca gerektiği kadar genişlet" olarak yorumlanabilir. Microsoft'un şartları "CenterAndExpandToParent" veya "CenterAndExpandAsNeeded" gibi daha az kafa karıştırıcı bir şeye değiştirmesi gerektiğini düşünüyorum
technoman23

1

Falko iyi bir açıklama yaptı ama başka bir görsel ve bu etiketlerin xaml'de nasıl çalıştığını eklemek istedim, çoğu zaman kullanmayı tercih ettiğim şey bu. Görüntü sonuçlarını test etmek için basit bir proje yaptım. İşte Ana Sayfa için Xaml:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Alignments.MainPage"
             BackgroundColor="White">


    <StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="LightGray" Padding="1" Margin="30">
        <Label Text="Vert: EndAndExpand, Horz: EndAndExpand" VerticalOptions="EndAndExpand" HorizontalOptions="EndAndExpand" BackgroundColor="White"/>
    </StackLayout>


</ContentPage>

Gördüğünüz gibi içinde bir etiket bulunan çok basit bir StackLayout. Aşağıdaki her görüntü için StackLayout'u aynı tuttum, sadece Giriş için yatay ve dikey seçenekleri değiştirdim ve metni seçilen seçenekleri gösterecek şekilde değiştirdim, böylece Giriş'in nasıl hareket ettiğini ve yeniden boyutlandırıldığını görebilirsiniz.

Start vs StartAndExpand Start için kullanılan kod şöyledir:

<Label Text="Vert: Start, Horz: Start" VerticalOptions="Start" HorizontalOptions="Start" BackgroundColor="White"/>

Ve StartAndExpand için kullanılan kod:

<Label Text="Vert: StartAndExpand, Horz: StartAndExpand" VerticalOptions="StartAndExpand" HorizontalOptions="StartAndExpand" BackgroundColor="White"/>

Gördüğünüz gibi görsel olarak StartAndExpand seçeneğinde kullanılandan daha fazla fark yoktur. Bu, Samsung A30 fiziksel cihazımda test edildi. Bunlar farklı cihazlarda farklı görünebilir, ancak bence buradaki tüm görüntüler toplu olarak Xamarin'de bazı hatalar olduğunu gösteriyor. Geri kalanı için sadece ekran görüntülerini göstereceğim, sanırım kendiliğinden anlaşılırlar.

End ve EndAndExpand Karşılaştırması

Center - CenterAndExpand Karşılaştırması

Fill ve FillAndExpand Karşılaştırması

Bazı ek ayrıntılar için Microsoft belgelerine de göz atmanızı öneririz . Dikkate değer "Genişletme yalnızca bir StackLayout tarafından kullanılır" dır.


Güzel görselleştirme. Ama bunun neden Xamarin'de böcek göstermesi gerektiğini anlamıyorum. Kafa karıştırıcı olabilecek şey, etiketlerin beyaz arka planlarından (örneğimdeki gri bölgeler) daha fazla yer kaplayabilmesidir. Böylece bir "Vert Center" etiketi, tüm sayfa içinde değil, kapladığı alanın ortasındadır. Görünüşe göre, neredeyse altı yıl sonra bu konu geri döndüğü kadar kafa karıştırıcı.
Falko
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.