Xamarin.Forms:如何使用相对布局居中视图?`Width`和`Height`返回-1

Bra*_*ick 7 c# xamarin xamarin.forms

当试图在Xamarin.Forms中使用控件的HeightWidth属性时,都返回-1,这会导致相对布局在屏幕上偏离中心.

var mainLayout = new RelativeLayout();

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

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

Content = mainLayout;
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

Bra*_*ick 16

为什么Xamarin.Forms返回-1 HeightWidth

Xamarin.Forms返回-1作为这些属性的默认值,并且它保持-1,直到Xamarin.Forms创建本机控件,例如UIButton,并将该本机控件添加到布局.

在此链接中,您可以看到返回-1默认值的Xamarin.Forms源代码:https: //github.com/xamarin/Xamarin.Forms/blob/master/Xamarin.Forms.Core/VisualElement.cs

使用相对布局来约束视图的最佳方法

选项1:本地功能(需要C#7.0或更高版本)

使用本地函数动态检索WidthHeight属性

var mainLayout = new RelativeLayout();

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

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

Content = mainLayout;

static double getWidth(RelativeLayout parent, View view) => view?.Measure(parent.Width, parent.Height).Request.Width ?? -1;
static double getHeight(RelativeLayout parent, View view) => view?.Measure(parent.Width, parent.Height).Request.Height ?? -1;
Run Code Online (Sandbox Code Playgroud)

选项2:本地功能(需要C#7.0或更高版本)

使用a Func<RelativeLayout, double>动态检索FuncWidth属性

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;
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

感谢@BrewMate教我这招!

  • 有没有办法在XAML中执行此操作? (15认同)
  • 这对于居中包含动态文本的标签也很有用!随着文本大小的增加/减少,相对布局将自动重新计算其宽度并保持标签居中! (2认同)
  • 我怎样才能在 xaml 中做到这一点?谢谢 ! (2认同)