让 Xamarin Forms 为您测量它们。然后将它们移动到位。
通过继承 AbsoluteLayout 并添加一个页面可以设置的 Action 来实现这一点,以便在您的布局完成时调用 LayoutChildren。
MyAbsoluteLayout.cs:
using System;
using Xamarin.Forms;
namespace XFSOAnswers
{
public class MyAbsoluteLayout : AbsoluteLayout
{
public MyAbsoluteLayout()
{
}
// Containing page will set this, to act on children during LayoutChildren.
public Action CustomLayoutAction { get; set; }
private bool _busy;
protected override void LayoutChildren(double x, double y, double width, double height)
{
// Avoid recursed layout calls as CustomLayoutAction moves children.
if (_busy)
return;
// Xamarin measures the children.
base.LayoutChildren(x, y, width, height);
_busy = true;
try
{
CustomLayoutAction?.Invoke();
}
finally
{
_busy = false;
// Layout again, to position the children, based on adjusted (x,y)s.
base.LayoutChildren(x, y, width, height);
}
}
}
}
示例用法 - MyAbsoluteLayoutPage.xaml:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:XFSOAnswers"
x:Class="XFSOAnswers.MyAbsoluteLayoutPage">
<ContentPage.Content>
<local:MyAbsoluteLayout x:Name="TheLayout">
<!-- Layout positions start (0,0). Adjusted later in PositionLabels. -->
<Label x:Name="Label1" Text="Welcome" />
<Label x:Name="Label2" Text="to" />
<Label x:Name="Label3" Text="Xamarin" />
<Label x:Name="Label4" Text=".Forms!" />
</local:MyAbsoluteLayout>
</ContentPage.Content>
</ContentPage>
MyAbsoluteLayoutPage.xaml.cs:
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace XFSOAnswers
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MyAbsoluteLayoutPage : ContentPage
{
public MyAbsoluteLayoutPage()
{
InitializeComponent();
TheLayout.CustomLayoutAction = PositionLabels;
}
private void PositionLabels()
{
// Optional: Set breakpoint after these, to check that the bounds have values.
var bounds1 = Label1.Bounds;
var bounds2 = Label2.Bounds;
var bounds3 = Label3.Bounds;
var bounds4 = Label4.Bounds;
double x = 10;
double y = 20;
MoveAbsoluteChildTo(Label1, x, y);
x += Label1.Width;
y += Label1.Height;
MoveAbsoluteChildTo(Label2, x, y);
x += Label2.Width;
y += Label2.Height;
MoveAbsoluteChildTo(Label3, x, y);
x += Label3.Width;
y += Label3.Height;
MoveAbsoluteChildTo(Label4, x, y);
}
private static void MoveAbsoluteChildTo(View child, double x, double y)
{
AbsoluteLayout.SetLayoutBounds(child, new Rect(x, y, child.Width, child.Height));
}
}
}
结果:
参见ToolmakerSteve - repo XFormsSOAnswers 中的MyAbsoluteLayout 和MyAbsoluteLayoutPage。