简体   繁体   English

Xamarin.Forms等效于layoutSubviews是什么?

[英]What is the Xamarin.Forms equivalent of layoutSubviews?

I'm porting a large iOS codebase to a Xamarin.Forms app. 我正在将大型iOS代码库移植到Xamarin.Forms应用程序。 We have a lot of custom views which perform their layout logic by making calculations in -layoutSubviews . 我们有很多自定义视图,这些视图通过在-layoutSubviews进行计算来执行其布局逻辑。 The codebase is too large for me to port in time if I need to reinterpret these calculations in terms of Stack or Grid layouts. 如果我需要根据堆栈或网格布局重新解释这些计算,则代码库太大,无法及时移植。 What I really want is a direct equivalent, where I can add the equivalent subviews to our views without worrying about where they go, and then a method which is called when the view's bounds change inside which I can set the new bounds of the subviews. 我真正想要的是一个直接等效项,可以在其中将等效子视图添加到我们的视图中,而不必担心它们的去向,然后是一个当视图范围更改时调用的方法,可以在其中设置子视图的新边界。 Then I can directly port our existing iOS code. 然后,我可以直接移植我们现有的iOS代码。

Is there some equivalent in Xamarin.Forms for -layoutSubviews ? Xamarin.Forms中是否有与-layoutSubviews等效的-layoutSubviews

I am not sure if there is a an equivalent in forms for layoutSubviews but the calculations that you are talking about can be done inside a method called: 我不确定layoutSubviews的表单是否等效,但是您正在谈论的计算可以在称为方法的内部完成:

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

You need to inherit from a ContentPage or Any Page to override this method. 您需要从ContentPage或Any Page继承以覆盖此方法。

You can create your own Layout by deriving from Xamarin.Forms.Layout class. 您可以通过继承Xamarin.Forms.Layout类来创建自己的Layout。

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

    }
}

The layout must override the LayoutChildren method. 布局必须覆盖LayoutChildren方法。 This method is responsible for positioning children on screen. 此方法负责将孩子放在屏幕上。

Children can be measured by using the GetSizeRequest method, which will return both the desired size and the minimum size the child desires. 可以通过使用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;
    }
}

This method will automatically be called whenever the layout needs to be recomputed. 每当需要重新计算布局时,都会自动调用此方法。 If your layout consists of hardcoded or fixed size elements, hard code their sizes into this algorithm instead of measuring. 如果布局由硬编码或固定大小的元素组成,则将其大小硬编码到此算法中,而不是进行测量。 GetSizeRequest calls are some of the most expensive calls that can be made, and are not predictable in their runtime as the subtree may be arbitrary complex. GetSizeRequest调用是可以进行的一些最昂贵的调用,并且在运行时不可预测,因为子树可能是任意复杂的。 Fixing their size is a great way to get a performance boost if dynamic sizing is not required. 如果不需要动态调整大小,则固定它们的大小是提高性能的一种好方法。

Implementing OnSizeRequest is required to make sure the new layout is sized correctly when placed inside other layouts. 需要执行OnSizeRequest以确保在将新布局放入其他布局中时正确调整其大小。 During layout cycles this method may be called many times depending on the layout above it and how many layout exceptions are required to resolve the current layout hierarchy. 在布局周期中,根据其上方的布局以及解析当前布局层次结构需要多少个布局例外,可能会多次调用此方法。

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));
}

You can read the whole tutorial of how to create a Custom layout here . 您可以在此处阅读有关如何创建自定义布局的整个教程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM