Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Android] Fix ScrollView filling layouts #17243

Merged
merged 14 commits into from
Oct 12, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,63 @@ public async Task DoesNotLeak()
Assert.False(platformReference.IsAlive, "PlatformView should not be alive!");
}

[Fact(DisplayName = "ScrollView inside layouts do not grow")]
public async Task DoesNotGrow()
{
var screenWidthConstraint = 600;
var screenHeightConstraint = 600;

var label = new Label() { Text = "Text inside a ScrollView" };
var scrollView = new ScrollView() { MaximumHeightRequest = 500, Content = label };
var parentLayout = new VerticalStackLayout { scrollView};
parentLayout.BackgroundColor = Colors.Blue;

SetupBuilder();

await CreateHandlerAndAddToWindow(parentLayout, () =>
{
var size = (parentLayout as IView).Measure(screenWidthConstraint, screenHeightConstraint);
var rect = new Rect(0, 0, size.Width, size.Height);
(parentLayout as IView).Arrange(rect); // Manual layout to prevent device test flakiness on Windows
});

Assert.True(parentLayout.Height > 0, "Parent layout should have non-zero height!");
Assert.True(parentLayout.Height < 500, "ScrollView should not make parent layout grow!");
}

[Fact (DisplayName = "ScrollView's viewport fills available space if set to fill"
#if MACCATALYST || IOS
, Skip = "See: https://github.com/dotnet/maui/issues/17700. If the issue is solved, re-enable the tests"
#endif
)]
public async Task ShouldGrow()
{
var screenWidthConstraint = 600;
var screenHeightConstraint = 600;

var label = new Label() { Text = "Text inside a ScrollView"};
var childLayout = new VerticalStackLayout { label };
var scrollView = new ScrollView() { VerticalOptions = LayoutOptions.Fill, Content = childLayout};
var parentLayout = new Grid { scrollView };

var expectedHeight = 100;
parentLayout.HeightRequest = expectedHeight;

SetupBuilder();

await CreateHandlerAndAddToWindow(parentLayout, () =>
{
var size = (parentLayout as IView).Measure(screenWidthConstraint, screenHeightConstraint);
var rect = new Rect(0, 0, size.Width, size.Height);
(parentLayout as IView).Arrange(rect); // Manual layout to prevent device test flakiness on Windows
});

// Android is usually off by one or two px. Hence the tolerance
Assert.Equal(scrollView.Height, childLayout.Height, 2.0);
Assert.Equal(parentLayout.Height, scrollView.Height, 2.0);
Assert.Equal(expectedHeight, parentLayout.Height, 2.0);
}

void SetupBuilder()
{
EnsureHandlerCreated(builder =>
Expand All @@ -119,6 +176,7 @@ void SetupBuilder()
handlers.AddHandler<Label, LabelHandler>();
handlers.AddHandler<IScrollView, ScrollViewHandler>();
handlers.AddHandler<Grid, LayoutHandler>();
handlers.AddHandler<VerticalStackLayout, LayoutHandler>();
});
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,12 @@ public override Size GetDesiredSize(double widthConstraint, double heightConstra

var orientation = virtualView.Orientation;

if (orientation == ScrollOrientation.Both || orientation == ScrollOrientation.Vertical)
if (!double.IsInfinity(heightConstraint) && (orientation == ScrollOrientation.Both || orientation == ScrollOrientation.Vertical))
{
heightSpec = AdjustSpecForAlignment(heightSpec, virtualView.VerticalLayoutAlignment);
}

if (orientation == ScrollOrientation.Both || orientation == ScrollOrientation.Horizontal)
if (!double.IsInfinity(widthConstraint) && (orientation == ScrollOrientation.Both || orientation == ScrollOrientation.Horizontal))
{
widthSpec = AdjustSpecForAlignment(widthSpec, virtualView.HorizontalLayoutAlignment);
}
Expand Down