使用比例坐标
在AbsoluteLayout中使用比例定位可能很棘手。 有時您需要補償考慮到大小的内部計算。 例如,您可能更喜歡指定坐标,以便X值為1表示子項的左邊緣位于AbsoluteLayout的右邊緣,您需要将其轉換為AbsoluteLayout了解的坐标。
在下面的讨論中,一個不考慮大小的坐标 - 一個坐标,其中1表示子項位于AbsoluteLay的右邊緣或底邊之外? - 被稱為小數坐标。本節的目标是開發将小數坐标轉換為可與AbsoluteLayout一起使用的比例坐标的規則。此配置檔案要求您知道子視圖的大小。
假設您将名為child的視圖放在名為absoluteLayout的AbsoluteLayout中,并為名為layoutBounds的子項設定布局邊界矩形。讓我們将此分析限制為水準坐标和大小。垂直坐标和尺寸的過程相同。
這個孩子必須先以某種方式獲得寬度。子節點可以計算自己的寬度,或者可以通過LayoutBounds附加屬性為與裝置無關的單元配置設定寬度。但是我們假設設定了AbsoluteLayoutFlags.WidthProportional标志,這意味着寬度是根據布局邊界的寬度字段和AbsoluteLay的寬度來計算的:
child.Width = layoutBounds.Width * absoluteLayout.Width
如果還設定了AbsoluteLayoutFlags.XProportional标志,那麼AbsoluteLayout内部通過考慮子項的大小來計算子項相對于自身的坐标:
relativeChildCorrdinate.X = (absoluteLayout.Width - child.Width) * layoutBounds.X
例如,如果AbsoluteLayout的寬度為400,而子節點的寬度為100,而layoutBounds.X為0.5,則relativeChildCoordinate.X計算為150.這意味着子節點的左邊緣為150 來自父級左邊緣的像素。 這會導緻子項在AbsoluteLayout中水準居中。
也可以計算小數子坐标:
fractionalChildCoordinate.X = relativeChildCoordinate.X / absoluteLayout.Width
這與比例坐标不同,因為小數子坐标為1意味着孩子的左邊緣恰好位于AbsoluteLayout的右邊緣之外,是以子項位于AbsoluteLayout的表面之外。 要繼續該示例,小數子坐标為150除以400或0.375。 子視圖的左側位于(0.375 * 400)或距離AbsoluteLayout左邊緣150個機關。
讓我們重新排列公式的術語,計算要為layoutBounds.X求解的相對子坐标:
layoutBounds.X = relativeChildCoordinate.X / (absoluteLayout.WIdth - child.Width)
讓我們将該比率的頂部和底部除以AbsoluteLayout的寬度:
layoutBounds.X = fractionalChildCoordinate.X / (1 - child.Width / absoluteLayout.Width)
如果你也使用比例寬度,那麼分母中的那個比例是layoutBounds.Width:
layoutBounds.X = fractionalChildCoordinate.X / ( 1 - layoutBounds.Width)
這通常是一個非常友善的公式,因為它允許您從小數子坐标轉換為比例坐标,以便在布局邊界矩形中使用。
在ChessboardProportional示例中,當col等于7時,fractionalChildCoordi?nate.X為7除以列數(8)或7/8。 分母是1減1/8(正方形的比例寬度),或者再次是7/8。 比例為1。
讓我們看一個公式在代碼中應用于小數坐标的示例。 Propor tionalCoordinateCalc程式嘗試使用粉紅色AbsoluteLayout上的八個藍色BoxView元素重制這個簡單的圖形:

整個數字有2:1的比例。 您可以将該圖視為包含四個水準矩形和四個垂直矩形。 頂部和底部的水準藍色矩形對具有0.1個分數機關的高度(相對于AbsoluteLayout的高度),并且從頂部和底部以及彼此之間間隔0.1個機關。 垂直的藍色矩形看起來間隔和尺寸相似,但由于縱橫比為2:1,垂直矩形的寬度為0.05個機關,并且從左側和右側以及彼此之間間隔0.05個機關。
AbsoluteLayout在XAML檔案中定義并居中,并以粉紅色着色:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ProportionalCoordinateCalc.ProportionalCoordinateCalcPage">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness"
iOS="5, 25, 5, 5"
Android="5"
WinPhone="5" />
</ContentPage.Padding>
<ContentView SizeChanged="OnContentViewSizeChanged">
<AbsoluteLayout x:Name="absoluteLayout"
BackgroundColor="Pink"
HorizontalOptions="Center"
VerticalOptions="Center" />
</ContentView>
</ContentPage>
代碼隐藏檔案定義了一個Rectangle結構數組,其中包含八個BoxView元素中每個元素的小數坐标。 在foreach循環中,程式應用上面顯示的最終公式的略微變化。 而不是分母等于1減去布局的值?Bounds.Width(或layoutBounds.Height),它使用小數界限的寬度(或高度),它是相同的值。
public partial class ProportionalCoordinateCalcPage : ContentPage
{
public ProportionalCoordinateCalcPage()
{
InitializeComponent();
Rectangle[] fractionalRects =
{
new Rectangle(0.05, 0.1, 0.90, 0.1), // outer top
new Rectangle(0.05, 0.8, 0.90, 0.1), // outer bottom
new Rectangle(0.05, 0.1, 0.05, 0.8), // outer left
new Rectangle(0.90, 0.1, 0.05, 0.8), // outer right
new Rectangle(0.15, 0.3, 0.70, 0.1), // inner top
new Rectangle(0.15, 0.6, 0.70, 0.1), // inner bottom
new Rectangle(0.15, 0.3, 0.05, 0.4), // inner left
new Rectangle(0.80, 0.3, 0.05, 0.4), // inner right
};
foreach (Rectangle fractionalRect in fractionalRects)
{
Rectangle layoutBounds = new Rectangle
{
// Proportional coordinate calculations.
X = fractionalRect.X / (1 - fractionalRect.Width),
Y = fractionalRect.Y / (1 - fractionalRect.Height),
Width = fractionalRect.Width,
Height = fractionalRect.Height
};
absoluteLayout.Children.Add(
new BoxView
{
Color = Color.Blue
},
layoutBounds,
AbsoluteLayoutFlags.All);
}
}
void OnContentViewSizeChanged(object sender, EventArgs args)
{
ContentView contentView = (ContentView)sender;
// Figure has an aspect ratio of 2:1.
double height = Math.Min(contentView.Width / 2, contentView.Height);
absoluteLayout.WidthRequest = 2 * height;
absoluteLayout.HeightRequest = height;
}
}
SizeChanged處理程式隻是修複了寬高比。
這是結果:
而且,當然,您可以将手機側向轉動,并在橫向模式下看到更大的數字,您必須通過側向翻書來檢視: