什么是Xamarin.Forms相当于layoutSubviews?

时间:2016-08-08 13:15:59

标签: c# ios xamarin.forms porting

我将大型iOS代码库移植到Xamarin.Forms应用程序。我们有很多自定义视图,通过在-layoutSubviews中进行计算来执行其布局逻辑。如果我需要根据Stack或Grid布局重新解释这些计算,那么代码库对我来说太大了。我真正想要的是一个直接的等价物,我可以在我们的视图中添加等效的子视图而不用担心他们去哪里,然后在视图的边界变化时调用的方法我可以设置新的边界子视图。然后我可以直接移植现有的iOS代码。

-layoutSubviews的Xamarin.Forms中是否有一些等价物?

2 个答案:

答案 0 :(得分:1)

我不确定layoutSubviews的表单中是否有等效表单,但您正在讨论的计算可以在一个名为

的方法中完成。
protected override void OnSizeAllocated(double width, double height)
{
    base.OnSizeAllocated(width, height);
}

您需要从ContentPage或Any Page继承以覆盖此方法。

答案 1 :(得分:1)

您可以通过从Xamarin.Forms.Layout类派生来创建自己的布局。

public class CustomLayout : Layout<View>
{
    public CustomLayout ()
    {

    }
}

布局必须覆盖LayoutChildren方法。此方法负责将儿童定位在屏幕上。

可以使用GetSizeRequest方法测量儿童,这将返回所需的大小和儿童所需的最小尺寸。

protected override void LayoutChildren (double x, double y, double width, double height)
{
    for (int i = 0; i < Children.Count; i++) {
        var child = (View) Children[i];
        // skip invisible children

        if(!child.IsVisible) 
            continue;
        var childSizeRequest = child.GetSizeRequest (double.PositiveInfinity, height);
        var childWidth = childSizeRequest.Request.Width;
        LayoutChildIntoBoundingRegion (child, new Rectangle (x, y, childWidth, height));
        x += childWidth;
    }
}

只要需要重新计算布局,就会自动调用此方法。如果您的布局由硬编码或固定大小的元素组成,则将其大小硬编码到此算法中而不是测量。 GetSizeRequest调用是可以进行的一些最昂贵的调用,并且在运行时无法预测,因为子树可能是任意复杂的。如果不需要动态调整大小,修复它们的大小是提高性能的好方法。

在放置在其他布局中时,需要实现OnSizeRequest以确保新布局的大小正确。在布局循环期间,可以多次调用此方法,具体取决于其上方的布局以及解析当前布局层次结构所需的布局异常数。

protected override SizeRequest OnSizeRequest (double widthConstraint, double heightConstraint)
{
    var height = 0;
    var minHeight = 0;
    var width = 0;
    var minWidth = 0;

    for (int i = 0; i < Children.Count; i++) {
        var child = (View) Children[i];
        // skip invisible children

        if(!child.IsVisible) 
            continue;
        var childSizeRequest = child.GetSizeRequest (double.PositiveInfinity, height);
        height = Math.Max (height, childSizeRequest.Minimum.Height);
        minHeight = Math.Max (minHeight, childSizeRequest.Minimum.Height);
        width += childSizeRequest.Request.Width;
        minWidth += childSizeRequest.Minimum.Width;
    }

    return new SizeRequest (new Size (width, height), new Size (minWidth, minHeight));
}

您可以阅读有关如何创建自定义布局here的整个教程。