首页 文章

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

提问于
浏览
7

当试图在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;

enter image description here

1 回答

  • 16

    为什么Xamarin.Forms为高度和宽度返回-1?

    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或更高版本)

    使用Local Function动态检索 WidthHeight 属性

    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;
    

    选项2:Func <RelativeLayout,double>

    使用 Func 动态检索 WidthHeight 属性

    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;
    

    enter image description here

    感谢@BrewMate教我这招!

相关问题