有什么方法可以强制执行OnSizeAllocated方法?

时间:2019-06-03 11:41:37

标签: xaml xamarin xamarin.forms

我使用Xaml代码创建了一个视图。我使用后面的代码来完成此操作,因为我想根据设备方向更改视图的布局。因此,我面临的问题是在加载视图后正在调用OnSizeAllocated方法。因此,无法根据设备方向更改布局。我只想知道在加载视图之前是否有任何方法可以调用OnSizeAllocated方法。请单击下面的链接查看代码:

Please click Here to view the Code

2 个答案:

答案 0 :(得分:2)

1. 重新排列页面

您可以检查宽度是否大于高度,以确定设备现在是横向还是纵向:

public partial class Page13 : ContentPage
{
    private double _width ;
    private double _height ;
    private Grid grid;
    private Label label;
    private Entry entry;
    private Button button;

    public Page13 ()
    {
        _width = this.Width;
        _height = this.Height;
        label = new Label(){Text = "i am a laber"};
        entry = new Entry(){WidthRequest = 200};
        button = new Button(){Text = "Submit"};
        grid = new Grid();
        UpdateLayout();
        StackLayout stackLayout = new StackLayout();
        stackLayout.Children.Add(grid);
        Content = stackLayout;

    }

    protected override void OnSizeAllocated(double width, double height)
    {
        base.OnSizeAllocated(width, height);
        if (_width != width || _height != height)
        {
            _width = width;
            _height = height;
            UpdateLayout();
        }
    }
    void UpdateLayout()
    {
        grid.RowDefinitions.Clear();
        grid.ColumnDefinitions.Clear();
        grid.Children.Clear();

        if (_width > _height)
        {
            ScreenRotatedToLandscape();
        }
        else
        {
            ScreenRotatedToPortrait();
        }
    }
    private void ScreenRotatedToLandscape()
    {
        grid.RowDefinitions.Add(new RowDefinition(){Height = new GridLength(1,GridUnitType.Auto)});
        grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) });
        grid.ColumnDefinitions.Add(new ColumnDefinition(){Width = new GridLength(1,GridUnitType.Auto)});
        grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Auto) });
        grid.Children.Add(label,0,0);
        grid.Children.Add(entry, 1, 0);
        grid.Children.Add(button, 0, 1);
        Grid.SetColumnSpan(button,2);
    }

    private void ScreenRotatedToPortrait()
    {
        grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) });
        grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) });
        grid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) });
        grid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Auto) });
        grid.Children.Add(label, 0, 0);
        grid.Children.Add(entry, 0, 1);
        grid.Children.Add(button, 0, 2);
    }
}

这是从Xamarin.Forms文档中直接获取的推荐实现。

2. 使用Xamarin.Essentials

它为Xamarin内置的跨平台应用程序添加了附加功能。这些新功能之一是能够通过访问DeviceDisplay.ScreenMetrics.Orientation属性以当前方向ping设备。这将返回当前设备的方向,可用于确定要呈现的布局。

与上面的类似

private bool IsPortrait;

public Page13 ()
{
     ...
     IsPortrait = DeviceDisplay.ScreenMetrics.Orientation == ScreenOrientation.Portrait;
     UpdateLayout();
     ...

}

void UpdateLayout()
{
    grid.RowDefinitions.Clear();
    grid.ColumnDefinitions.Clear();
    grid.Children.Clear();

    if (IsPortrait)
    {
        ScreenRotatedToPortrait();
    }
    else
    {
        ScreenRotatedToLandscape();
    }
}

答案 1 :(得分:0)

由于SizeAllocation尚未更改,您不能强行运行该命令,但是您可以这样做来获得初始载荷的方向:

  1. 如果添加Xamarin.Essentials nuget软件包as you can see here,,则可以使用此行代码DeviceDisplay.MainDisplayInfo.Orientation获取方向,您将获得Landscape,Portrait,Square或Unknown。
  2. 如果不想添加包,则可以使用Application.Current.MainPage.Width和Application.Current.MainPage.Height来确定方向。