Sự khác biệt giữa Bố cục của Xamarin.Form, đặc biệt là Điền và Mở rộng là gì?


170

Trong Xamarin.Forms, mọi thứ đều Viewcó hai thuộc tính HorizontalOptionsVerticalOptions. Cả hai đều thuộc loại LayoutOptionsvà có thể có một trong các giá trị sau:

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

Rõ ràng nó kiểm soát sự liên kết của khung nhìn trên khung nhìn cha. Nhưng chính xác thì hành vi của từng lựa chọn cá nhân như thế nào? Và sự khác biệt giữa Fillvà hậu tố là Expandgì?

Câu trả lời:


335

Câu trả lời ngắn

Start, Center, EndFillđịnh nghĩa của quan điểm liên kết trong không gian của nó .

Expandxác định xem nó chiếm nhiều không gian hơn nếu có.

Học thuyết

Cấu trúc LayoutOptionskiểm soát hai hành vi khác nhau:

  1. Căn chỉnh: Chế độ xem được căn chỉnh trong chế độ xem cha mẹ như thế nào?

    • Start: Đối với căn dọc, chế độ xem được di chuyển lên trên cùng. Đối với căn ngang, đây thường là phía bên trái. (Nhưng lưu ý rằng trên các thiết bị có cài đặt ngôn ngữ từ phải sang trái, đây là cách khác, nghĩa là căn phải.)
    • Center: Chế độ xem được đặt ở giữa.
    • End: Thông thường chế độ xem là đáy hoặc căn phải. (Tất nhiên, trên các ngôn ngữ từ phải sang trái, tất nhiên, được căn trái.)
    • Fill: Căn chỉnh này là hơi khác nhau. Chế độ xem sẽ trải dài trên toàn bộ kích thước của chế độ xem chính.

    Tuy nhiên, nếu cha mẹ không lớn hơn thì con cái của bạn, bạn sẽ không nhận thấy bất kỳ sự khác biệt nào giữa các sắp xếp đó. Căn chỉnh chỉ quan trọng đối với quan điểm của phụ huynh với không gian bổ sung có sẵn.

  2. Mở rộng: Phần tử sẽ chiếm nhiều không gian hơn nếu có?

    • Hậu tố Expand: Nếu chế độ xem cha mẹ lớn hơn kích thước kết hợp của tất cả các con của nó, tức là không gian bổ sung có sẵn, thì không gian đó được cân đối giữa các chế độ xem con với hậu tố đó. Những đứa trẻ đó sẽ "chiếm" không gian của chúng, nhưng không nhất thiết phải "lấp đầy" nó. Chúng ta sẽ xem xét hành vi này trong ví dụ dưới đây.
    • Không có hậu tố: Những đứa trẻ không có Expandhậu tố sẽ không có thêm không gian, ngay cả khi có nhiều không gian hơn.

    Một lần nữa, nếu chế độ xem cha mẹ không lớn hơn con cái của nó, hậu tố mở rộng cũng không tạo ra bất kỳ sự khác biệt nào.

Thí dụ

Chúng ta hãy xem ví dụ sau để thấy sự khác biệt giữa tất cả tám tùy chọn bố cục.

Ứng dụng chứa một màu xám đen StackLayoutvới tám nút trắng lồng nhau, mỗi nút được gắn nhãn với tùy chọn bố cục dọc. Khi nhấp vào một trong các nút, nó sẽ gán tùy chọn bố trí dọc cho bố cục ngăn xếp. Bằng cách này, chúng ta có thể dễ dàng kiểm tra sự tương tác của các chế độ xem với cha mẹ, cả hai với tùy chọn bố cục khác nhau.

(Một vài dòng mã cuối cùng thêm các hộp màu vàng bổ sung. Chúng tôi sẽ quay lại vấn đề này ngay lập tức.)

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

Các ảnh chụp màn hình sau đây cho thấy kết quả khi nhấp vào từng nút trong số tám nút. Chúng tôi thực hiện các quan sát sau đây:

  • Miễn là cha mẹ stackLayoutchặt chẽ (không phải Filltrang), tùy chọn bố cục dọc của mỗi trang Buttonlà không đáng kể.
  • Tùy chọn bố trí dọc chỉ quan trọng nếu stackLayoutlớn hơn (ví dụ thông qua Fillcăn chỉnh) và các nút riêng lẻ có Expandhậu tố.
  • Không gian bổ sung được cân đối giữa tất cả các nút có Expandhậu tố. Để thấy rõ hơn điều này, chúng tôi đã thêm các đường ngang màu vàng giữa mỗi hai nút lân cận.
  • Các nút có nhiều không gian hơn chiều cao yêu cầu của chúng không nhất thiết phải "lấp đầy" nó. Trong trường hợp này hành vi thực tế được kiểm soát bởi sự liên kết của họ. Ví dụ, chúng được căn chỉnh trên đỉnh, giữa hoặc nút của không gian của chúng hoặc điền vào nó hoàn toàn.
  • Tất cả các nút trải dài trên toàn bộ chiều rộng của bố cục, vì chúng tôi chỉ sửa đổi VerticalOptions.

Ảnh chụp màn hình

Ở đây bạn tìm thấy các ảnh chụp màn hình độ phân giải cao tương ứng.


6
hình ảnh trông giống như [[midfing]], lol. đùa thôi, nó thực sự hữu ích
Joy Rex

1
@JoyRex: Chà, có lẽ phiên bản này ít gây nhầm lẫn hơn. ;)
Falko

2
Tôi đã nhầm lẫn với đầu ra trên. start & startAndExpand cả hai đều có cùng một đầu ra .. Sự khác biệt giữa chúng là gì? bạn có thể đưa ra lời giải thích nếu có thể ..
Ranjith Kumar

1
FillAndExpandlà những gì bạn muốn, 99% cho thời gian
Stephane Delcroix

1
@RanjithKumar Họ giống nhau. Nó StackLayout được lồng trong một cha mẹ khác sau đó FillAndExpand của nó có thể tạo ra sự khác biệt - nó sẽ mở rộng trong phạm vi cha mẹ của nó .
Miha Markic

16

Có một chút lỗi trong phiên bản hiện tại của Xamarin.Forms; có lẽ nó đã ở đó một thời gian

CenterAndExpand nói chung không mở rộng và làm việc xung quanh nó có thể gây nhầm lẫn.

Ví dụ: nếu bạn có một StackLayoutbộ thành CenterAndExpand, thì bạn đặt một nhãn bên trong cũng được đặt thành CenterAndExpandbạn sẽ mong muốn một nhãn có chiều rộng đầy đủ của StackLayout. Không. Nó sẽ không mở rộng. Bạn phải đặt thành StackLayout" FillAndExpand" để làm cho đối tượng Nhãn lồng nhau mở rộng ra toàn bộ chiều rộng của nó StackLayout, sau đó báo cho Nhãn để căn giữa văn bản, chứ không phải là một đối tượng HorizontalTextAlignment="Center". Theo kinh nghiệm của tôi, bạn cần đặt cả cha mẹ và con lồngFillAndExpand nếu bạn thực sự muốn đảm bảo nó mở rộng để phù hợp.

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

3
"... bạn sẽ mong đợi một nhãn có chiều rộng đầy đủ của StackLayout." Giả định này không chính xác. Expandchỉ được sử dụng cho trẻ em của StackLayout. Vì vậy, nếu StackLayout của bạn là root, hoặc không phải trong StackLayout khác, Expandkhông có ảnh hưởng. Thay vào đó, bất kỳ tùy chọn nào khác ngoài Fill sẽ đóng vai trò là "bọc nội dung" để định cỡ, đó là những gì bạn thấy.
Therealjohn 6/12/2016

Ngoài ra, việc mở rộng chỉ hoạt động đối với LayoutOptions có cùng định hướng của StackLayout. Trong trường hợp này, bố cục là "Dọc", nhưng các tùy chọn trong câu hỏi là Ngang (đối lập).
trị liệu

Thuật ngữ "AndExpand" không rõ ràng. Nó có thể được hiểu là "mở rộng càng nhiều càng tốt" hoặc "chỉ mở rộng càng nhiều càng cần thiết". Tôi nghĩ rằng Microsoft nên thay đổi các điều khoản thành một cái gì đó ít gây nhầm lẫn hơn, như "CenterAndExpandToParent" hoặc "CenterAndExpandAsNeeded"
technoman23

1

Falko đã đưa ra một lời giải thích tốt nhưng tôi muốn thêm vào đó bằng một hình ảnh khác và cách các thẻ này hoạt động trong xaml, đó là điều tôi thích sử dụng hầu hết thời gian. Tôi đã thực hiện một dự án đơn giản để thử nghiệm kết quả hiển thị. Đây là Xaml cho Trang chính:

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

Như bạn có thể thấy đó là một StackLayout rất đơn giản với một Nhãn bên trong. Đối với mỗi hình ảnh bên dưới, tôi vẫn giữ StackLayout như nhau, tôi chỉ thay đổi các tùy chọn ngang và dọc cho Entry và thay đổi văn bản để hiển thị các tùy chọn đã chọn, để bạn có thể thấy cách Entry di chuyển và thay đổi kích thước.

Bắt đầu so với StartAndExpand Đây là mã được sử dụng cho Bắt đầu:

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

Và mã được sử dụng cho StartAndExpand:

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

Như bạn có thể thấy không có sự khác biệt về mặt trực quan ngoài việc có nhiều văn bản được sử dụng trong tùy chọn StartAndExpand. Điều này đã được thử nghiệm trên thiết bị vật lý Samsung A30 của tôi. Chúng có thể hiển thị khác nhau trên các thiết bị khác nhau, nhưng tôi nghĩ rằng tất cả các hình ảnh ở đây đều cho thấy rằng có một số lỗi trong Xamarin. Đối với phần còn lại tôi sẽ chỉ hiển thị các ảnh chụp màn hình, tôi nghĩ rằng chúng là tự giải thích.

Kết thúc so với EndAndExpand

Center vs CenterAndExpand

Điền so với FillAndExpand

Tôi cũng khuyên bạn nên xem tài liệu của Microsoft để biết thêm chi tiết. Đáng chú ý là "Mở rộng chỉ được sử dụng bởi StackLayout".


Hình dung đẹp. Nhưng tôi không thấy lý do tại sao điều này sẽ hiển thị lỗi trong Xamarin. Điều có thể gây nhầm lẫn là các nhãn có thể chiếm nhiều không gian hơn nền trắng của chúng (các vùng màu xám trong ví dụ của tôi). Vì vậy, nhãn "Trung tâm Vert" được đặt ở giữa không gian mà nó chiếm - không nằm trong toàn bộ trang. Rõ ràng, sau gần sáu năm, chủ đề này vẫn còn khó hiểu như nó đã trở lại.
Falko
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.