Ensure that AbsoluteLayout measures children at their target sizes (#3322)

This commit is contained in:
E.Z. Hart 2021-11-10 09:02:52 -07:00 коммит произвёл GitHub
Родитель f1cdd47912
Коммит c905fd6260
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
2 изменённых файлов: 61 добавлений и 3 удалений

Просмотреть файл

@ -33,14 +33,16 @@ namespace Microsoft.Maui.Layouts
continue;
}
var measure = child.Measure(availableWidth, availableHeight);
var bounds = AbsoluteLayout.GetLayoutBounds(child);
var flags = AbsoluteLayout.GetLayoutFlags(child);
bool isWidthProportional = HasFlag(flags, AbsoluteLayoutFlags.WidthProportional);
bool isHeightProportional = HasFlag(flags, AbsoluteLayoutFlags.HeightProportional);
var measureWidth = ResolveChildMeasureConstraint(bounds.Width, isWidthProportional, widthConstraint);
var measureHeight = ResolveChildMeasureConstraint(bounds.Height, isHeightProportional, heightConstraint);
var measure = child.Measure(measureWidth, measureHeight);
var width = ResolveDimension(isWidthProportional, bounds.Width, availableWidth, measure.Width);
var height = ResolveDimension(isHeightProportional, bounds.Height, availableHeight, measure.Height);
@ -122,5 +124,21 @@ namespace Microsoft.Maui.Layouts
return value;
}
static double ResolveChildMeasureConstraint(double boundsValue, bool proportional, double constraint)
{
if (boundsValue < 0)
{
// If the child view doesn't have bounds set by the AbsoluteLayout, then we'll measure using the full constraint value
return constraint;
}
if (proportional)
{
return boundsValue * constraint;
}
return boundsValue;
}
}
}

Просмотреть файл

@ -405,5 +405,45 @@ namespace Microsoft.Maui.UnitTests.Layouts
Assert.Equal(arrangedWidth, actual.Width);
Assert.Equal(arrangedHeight, actual.Height);
}
[Fact]
public void ChildMeasureRespectsAbsoluteBounds()
{
double expectedWidth = 115;
double expectedHeight = 230;
var abs = CreateTestLayout();
var child = CreateTestView();
SubstituteChildren(abs, child);
var childBounds = new Rectangle(0, 0, expectedWidth, expectedHeight);
SetLayoutBounds(abs, child, childBounds);
var gridLayoutManager = new AbsoluteLayoutManager(abs);
var measure = gridLayoutManager.Measure(double.PositiveInfinity, double.PositiveInfinity);
child.Received().Measure(Arg.Is(expectedWidth), Arg.Is(expectedHeight));
}
[Fact]
public void ChildMeasureRespectsProportionalBounds()
{
double expectedWidth = 0.5;
double expectedHeight = 0.6;
double widthConstraint = 200;
double heightConstraint = 200;
var abs = CreateTestLayout();
var child = CreateTestView();
SubstituteChildren(abs, child);
var childBounds = new Rectangle(0, 0, expectedWidth, expectedHeight);
SetLayoutBounds(abs, child, childBounds);
SetLayoutFlags(abs, child, AbsoluteLayoutFlags.SizeProportional);
var gridLayoutManager = new AbsoluteLayoutManager(abs);
var measure = gridLayoutManager.Measure(widthConstraint, heightConstraint);
child.Received().Measure(Arg.Is(expectedWidth * widthConstraint), Arg.Is(expectedHeight * heightConstraint));
}
}
}