Xamarin.Forms: How to center views using Relative Layout? `Width` and `Height` return -1

橙三吉。 提交于 2019-11-28 10:15:53

Why does Xamarin.Forms return -1 for Height and Width?

Xamarin.Forms returns -1 as the default value for these properties, and it remains -1 until Xamarin.Forms creates the native control, e.g. UIButton, and adds that native control to the layout.

In this link, you can see the Xamarin.Forms source code returning -1 as the default value: https://github.com/xamarin/Xamarin.Forms/blob/master/Xamarin.Forms.Core/VisualElement.cs

Best Way to Use Relative Layouts to Constrain Views

Option 1: Local Functions (Requires C# 7.0 or higher)

Use a Local Function to dynamically retrieve the Width and Height properties

var mainLayout = new RelativeLayout();

//Add the Switch to the center of the screen
mainLayout.Children.Add(mySwitch,
    Constraint.RelativeToParent(parent => parent.Width / 2 - getSwitchWidth(parent)/ 2),
    Constraint.RelativeToParent(parent => parent.Height / 2 - getSwitchHeight(parent) / 2));

//Add a Label below the switch
mainLayout.Children.Add(switchLabel,
    Constraint.RelativeToParent(parent => parent.Width / 2 - getLabelWidth(parent) / 2),
    Constraint.RelativeToView(mySwitch, (parent, view) => view.Y + getSwitchHeight(parent) + 10));

Content = mainLayout;

double getSwitchWidth(RelativeLayout parent) => mySwitch.Measure(parent.Width, parent.Height).Request.Width;
double getSwitchHeight(RelativeLayout parent) => mySwitch.Measure(parent.Width, parent.Height).Request.Height;
double getLabelWidth(RelativeLayout parent) => switchLabel.Measure(parent.Width, parent.Height).Request.Width;
double getLabelHeight(RelativeLayout parent) => switchLabel.Measure(parent.Width, parent.Height).Request.Height;

Option 2: Func<RelativeLayout, double>

Use a Func to dynamically retrieve the Width and Height properties

var mainLayout = new RelativeLayout();

Func<RelativeLayout, double> getSwitchWidth = (parent) => mySwitch.Measure(parent.Width, parent.Height).Request.Width;
Func<RelativeLayout, double> getSwitchHeight = (parent) => mySwitch.Measure(parent.Width, parent.Height).Request.Height;
Func<RelativeLayout, double> getLabelWidth = (parent) => switchLabel.Measure(parent.Width, parent.Height).Request.Width;
Func<RelativeLayout, double> getLabelHeight = (parent) => switchLabel.Measure(parent.Width, parent.Height).Request.Height;

//Add the Switch to the center of the screen
mainLayout.Children.Add(mySwitch,
    Constraint.RelativeToParent(parent => parent.Width / 2 - getSwitchWidth(parent)/ 2),
    Constraint.RelativeToParent(parent => parent.Height / 2 - getSwitchHeight(parent) / 2));

//Add a Label below the switch
mainLayout.Children.Add(switchLabel,
    Constraint.RelativeToParent(parent => parent.Width / 2 - getLabelWidth(parent) / 2),
    Constraint.RelativeToView(mySwitch, (parent, view) => view.Y + getSwitchHeight(parent) + 10));

Content = mainLayout;

Thanks to @BrewMate for teaching me this trick!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!