您可以通过从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 的完整教程。