Apa perbedaan antara LayoutOptions Xamarin.Form, terutama Fill dan Expand?

170

Dalam Xamarin. Bentuk setiap Viewproperti memiliki dua HorizontalOptionsdan VerticalOptions. Keduanya bertipe LayoutOptionsdan dapat memiliki salah satu dari nilai berikut:

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

Tampaknya itu mengontrol perataan tampilan pada tampilan induk. Tetapi bagaimana tepatnya perilaku masing-masing pilihan individu? Dan apa perbedaan antara Filldan sufiks Expand?

Falko
sumber

Jawaban:

335

Jawaban singkat

Start, Center, EndDan Fillmenentukan pandangan ini keselarasan dalam ruang yang .

Expandmendefinisikan apakah ia menempati lebih banyak ruang jika tersedia.

Teori

Struktur LayoutOptionsmengontrol dua perilaku berbeda:

  1. Alignment: Bagaimana tampilan selaras dalam tampilan induk?

    • Start: Untuk penyelarasan vertikal, tampilan dipindahkan ke atas. Untuk penyejajaran horisontal ini biasanya sisi kiri. (Tetapi perhatikan, bahwa pada perangkat dengan pengaturan bahasa kanan-ke-kiri ini adalah sebaliknya, yaitu disejajarkan dari kanan.)
    • Center: Tampilan terpusat.
    • End: Biasanya tampilan bawah atau kanan rata. (Pada bahasa kanan-ke-kiri, tentu saja, selaras kiri.)
    • Fill: Penjajaran ini sedikit berbeda. Tampilan akan membentang di seluruh ukuran tampilan induk.

    Namun, jika orang tua tidak lebih besar dari anak-anaknya, Anda tidak akan melihat adanya perbedaan antara keberpihakan tersebut. Penyelarasan hanya penting untuk tampilan induk dengan ruang tambahan yang tersedia.

  2. Ekspansi: Akankah elemen menempati lebih banyak ruang jika tersedia?

    • Suffix Expand: Jika tampilan orang tua lebih besar dari ukuran gabungan dari semua anak-anaknya, yaitu ruang tambahan tersedia, maka ruang tersebut proporsional di antara tampilan anak dengan suffix itu. Anak-anak itu akan "menempati" ruang mereka, tetapi tidak perlu "mengisinya". Kita akan melihat perilaku ini dalam contoh di bawah ini.
    • Tanpa akhiran: Anak-anak tanpa Expandakhiran tidak akan mendapatkan ruang tambahan, bahkan jika lebih banyak ruang tersedia.

    Sekali lagi, jika pandangan orang tua tidak lebih besar dari anak-anaknya, akhiran ekspansi tidak membuat perbedaan juga.

Contoh

Mari kita lihat contoh berikut untuk melihat perbedaan antara delapan opsi tata letak.

Aplikasi ini berisi abu-abu gelap StackLayoutdengan delapan tombol putih bersarang, yang masing-masing dilabeli dengan opsi tata letak vertikal. Ketika mengklik salah satu tombol, itu menetapkan opsi tata letak vertikal ke tata letak tumpukan. Dengan cara ini kita dapat dengan mudah menguji interaksi pandangan dengan orang tua, keduanya dengan opsi tata letak yang berbeda.

(Beberapa baris kode terakhir menambahkan kotak kuning tambahan. Kami akan kembali sebentar lagi.)

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,
        });
    }
}

Tangkapan layar berikut menunjukkan hasilnya ketika mengklik masing-masing dari delapan tombol. Kami melakukan pengamatan berikut:

  • Selama induknya stackLayoutkencang (tidak Fillhalaman), opsi tata letak vertikal masing-masing Buttondiabaikan.
  • Pilihan tata letak vertikal hanya penting jika stackLayoutlebih besar (mis. Via Fillpenyelarasan) dan masing-masing tombol memiliki Expandakhiran.
  • Ruang tambahan akhirnya proporsional di antara semua tombol dengan Expandakhiran. Untuk melihat ini lebih jelas, kami menambahkan garis horizontal kuning antara setiap dua tombol yang berdekatan.
  • Tombol dengan ruang lebih dari ketinggian yang diminta tidak harus "mengisinya". Dalam hal ini perilaku aktual dikendalikan oleh penyelarasannya. Misalnya mereka disejajarkan di atas, tengah atau tombol ruang mereka atau mengisinya sepenuhnya.
  • Semua tombol menjangkau seluruh lebar tata letak, karena kami hanya memodifikasi VerticalOptions.

Tangkapan layar

Di sini Anda menemukan tangkapan layar resolusi tinggi yang sesuai.

Falko
sumber
6
gambar tampak seperti [[midfing]], lol. hanya bercanda itu sangat membantu
Joy Rex
1
@JoyRex: Yah, mungkin versi ini agak kurang membingungkan. ;)
Falko
2
Saya bingung dengan output di atas. start & startAndExpand keduanya output yang sama .. Apa perbedaan di antara ini? dapatkah Anda memberikan penjelasan jika mungkin ..
Ranjith Kumar
1
FillAndExpandadalah apa yang Anda inginkan, 99% untuk saat itu
Stephane Delcroix
1
@RanjithKumar Mereka sama. Hal StackLayout itu bersarang di orang tua lain maka FillAndExpand bisa membuat perbedaan - itu akan memperluas dalam nya orang tua.
Miha Markic
16

Ada sedikit bug di versi Xamarin saat ini. mungkin sudah ada beberapa saat.

CenterAndExpand umumnya tidak berkembang, dan mengatasinya bisa membingungkan.

Misalnya jika Anda memiliki StackLayoutset untuk CenterAndExpand, maka Anda meletakkan label di dalamnya yang juga diatur untuk CenterAndExpandAnda akan mengharapkan label yang lebar penuh StackLayout. Nggak. Itu tidak akan berkembang. Anda harus mengatur StackLayout" FillAndExpand" ke untuk mendapatkan objek Label bersarang untuk memperluas ke lebar penuh StackLayout, kemudian memberi tahu Label untuk memusatkan teks, bukan dirinya sebagai objek, dengan HorizontalTextAlignment="Center". Dalam pengalaman saya, Anda perlu mengatur orang tua dan anak bersarang FillAndExpandjika Anda benar-benar ingin memastikan itu sesuai agar sesuai.

        <StackLayout HorizontalOptions="FillAndExpand"
                     Orientation="Vertical"
                     WidthRequest="300">
            <Label BackgroundColor="{StaticResource TileAlerts}"
                   HorizontalOptions="FillAndExpand"
                   Style="{StaticResource LabelStyleReversedLrg}"
                   HorizontalTextAlignment="Center"
                   Text="Alerts" />
Clint StLaurent
sumber
3
"... kamu akan mengharapkan label yang lebar penuh dari StackLayout." Asumsi ini salah. Expandhanya digunakan untuk anak-anak StackLayout. Jadi, jika StackLayout Anda adalah root, atau tidak di StackLayout lain, Expandtidak akan berpengaruh. Sebaliknya, opsi apa pun selain Isi akan bertindak sebagai "bungkus konten" untuk menentukan ukuran, yang merupakan apa yang Anda lihat.
therealjohn
Selain itu, ekspansi hanya berfungsi untuk LayoutOptions yang memiliki orientasi yang sama dengan StackLayout. Dalam hal ini, tata letaknya "Vertikal", tetapi opsi yang dimaksud adalah Horisontal (berlawanan).
therealjohn
Istilah "AndExpand" tidak jelas. Ini dapat diartikan sebagai "memperluas sebanyak mungkin" atau "memperluas hanya sebanyak yang diperlukan". Saya pikir Microsoft harus mengubah istilah menjadi sesuatu yang kurang membingungkan, seperti "CenterAndExpandToParent" atau "CenterAndExpandAsNeeded"
technoman23
1

Falko memberikan penjelasan yang baik tetapi saya ingin menambahkannya dengan visual lain dan bagaimana tag ini bekerja di xaml, yang mana saya lebih suka menggunakan sebagian besar waktu. Saya membuat proyek sederhana untuk menguji hasil tampilan. Inilah Xaml untuk Halaman Utama:

<?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>

Seperti yang Anda lihat itu adalah StackLayout yang sangat sederhana dengan Label di dalamnya. Untuk setiap gambar di bawah ini, saya menjaga StackLayout tetap sama, saya hanya mengubah opsi horizontal dan vertikal untuk Entri dan mengubah teks untuk menampilkan opsi yang dipilih, sehingga Anda dapat melihat bagaimana Entri bergerak dan mengubah ukuran.

Mulai vs StartAndExpand Berikut adalah kode yang digunakan untuk Mulai:

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

Dan kode yang digunakan untuk StartAndExpand:

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

Seperti yang Anda lihat tidak ada perbedaan secara visual selain ada lebih banyak teks yang digunakan dalam opsi StartAndExpand. Ini diuji pada perangkat fisik Samsung A30 saya. Ini mungkin ditampilkan secara berbeda pada perangkat yang berbeda, tapi saya pikir semua gambar di sini secara kolektif menunjukkan bahwa ada beberapa bug di Xamarin. Untuk sisanya saya hanya akan menunjukkan tangkapan layar, saya pikir mereka cukup jelas.

End vs EndAndExpand

Center vs CenterAndExpand

Isi vs FillAndExpand

Saya juga merekomendasikan untuk melihat dokumentasi Microsoft untuk beberapa detail tambahan. Yang perlu diperhatikan adalah "Ekspansi hanya digunakan oleh StackLayout".

technoman23
sumber
Visualisasi yang bagus. Tapi saya tidak mengerti mengapa ini menunjukkan bug di Xamarin. Apa yang mungkin membingungkan adalah bahwa label dapat menempati lebih banyak ruang daripada latar belakang putihnya (wilayah abu-abu dalam contoh saya). Jadi label "Vert Center" berada di tengah ruang yang ditempati - bukan di seluruh halaman. Rupanya, setelah hampir enam tahun topik ini masih membingungkan seperti dulu.
Falko