オーバーライドサイズの制約 - 親からの最終Layout
パスとしてレイアウトはこの値をオーバーライドします。 XF記事hereがこれについて詳細に話します。
正方形レイアウトを実現するには、これらの制約を考慮して親レイアウトを更新し、レイアウトパスで確実に渡す必要があります。
例えば、AbsoluteLayout
を拡張して、子供のサイズ制限を動的に計算することができます。このカスタムレイアウトは、すべての子をデフォルトで四角形として扱います。特定の子の動作をオーバーライドするには、添付プロパティーSquareLayout.IsSquare
をfalse
と設定することができます。
public class SquareLayout : AbsoluteLayout
{
public static readonly BindableProperty IsSquareProperty =
BindableProperty.CreateAttached("IsSquare",
typeof(bool),
typeof(SquareLayout),
defaultValue: true,
defaultBindingMode: BindingMode.OneWay);
public static bool GetIsSquare(BindableObject view)
{
return (bool)view.GetValue(IsSquareProperty);
}
public static void SetIsSquare(BindableObject view, bool value)
{
view.SetValue(IsSquareProperty, value);
}
Dictionary<View, Rectangle> _boundsCache = new Dictionary<View, Rectangle>();
protected override void LayoutChildren(double x, double y, double width, double height)
{
foreach(var child in Children)
{
var isSquare = GetIsSquare(child);
if(isSquare)
{
Rectangle bounds;
if (!_boundsCache.ContainsKey(child))
_boundsCache[child] = bounds = GetLayoutBounds(child);
else
bounds = _boundsCache[child];
var absFlags = GetLayoutFlags(child);
var widthIsProportional = (absFlags & AbsoluteLayoutFlags.WidthProportional) != 0;
var heightIsProportional = (absFlags & AbsoluteLayoutFlags.HeightProportional) != 0;
var childWidth = widthIsProportional ? bounds.Width * width : bounds.Width;
var childHeight = heightIsProportional ? bounds.Height * height : bounds.Height;
var size = Math.Min(childWidth, childHeight);
SetLayoutBounds(
child,
new Rectangle(
bounds.X,
bounds.Y,
(widthIsProportional ? (size/width) : size),
(heightIsProportional ? (size/height) : size)
)
);
}
}
base.LayoutChildren(x, y, width, height);
}
}
使用例:うわー素晴らしい説明
<local:SquareLayout>
<AbsoluteLayout BackgroundColor="Green"
AbsoluteLayout.LayoutBounds=".1,.1,1,1"
AbsoluteLayout.LayoutFlags="All" />
<AbsoluteLayout BackgroundColor="Blue"
AbsoluteLayout.LayoutBounds=".5,.5,.2,.1"
AbsoluteLayout.LayoutFlags="All" />
<AbsoluteLayout BackgroundColor="Red"
AbsoluteLayout.LayoutBounds=".9,.9,200,200"
AbsoluteLayout.LayoutFlags="PositionProportional" />
<AbsoluteLayout BackgroundColor="Yellow"
AbsoluteLayout.LayoutBounds="10,20,.3,.3"
AbsoluteLayout.LayoutFlags="SizeProportional" />
<AbsoluteLayout BackgroundColor="Silver"
local:SquareLayout.IsSquare="false"
AbsoluteLayout.LayoutBounds=".9,.9,1,.1"
AbsoluteLayout.LayoutFlags="All" />
</local:SquareLayout>
!!理解していただきありがとうございます:) – Maximus