Xamarin.Forms layoutSubviews 的等价物是什么?

What is the Xamarin.Forms equivalent of layoutSubviews?

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

在 Xamarin.Forms 中是否有一些等同于 -layoutSubviews 的东西?

我不确定 layoutSubviews 的表单中是否有等效项,但您所说的计算可以在一个名为的方法中完成:

protected override void OnSizeAllocated(double width, double height)
{
    base.OnSizeAllocated(width, height);
}

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

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

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

    }
}

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

Children 可以使用 GetSizeRequest 方法来测量,这将 return 所需的大小和 child 所需的最小大小。

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