Skip to content

Commit 4557b63

Browse files
PureWeenkubaflo
andcommitted
Fix Android ScrollView to Measure Content Correct
Co-authored-by: kubaflo <42434498+kubaflo@users.noreply.github.com>
1 parent ca9a7b6 commit 4557b63

File tree

4 files changed

+51
-31
lines changed

4 files changed

+51
-31
lines changed

src/Controls/src/Core/ScrollView/ScrollView.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,8 @@ Size ICrossPlatformLayout.CrossPlatformArrange(Rect bounds)
515515
return bounds.Size;
516516
}
517517

518-
Size IContentView.CrossPlatformMeasure(double widthConstraint, double heightConstraint) => ((ICrossPlatformLayout)this).CrossPlatformMeasure(widthConstraint, heightConstraint);
518+
Size IContentView.CrossPlatformMeasure(double widthConstraint, double heightConstraint) =>
519+
((ICrossPlatformLayout)this).CrossPlatformMeasure(widthConstraint, heightConstraint);
519520

520521
Size IContentView.CrossPlatformArrange(Rect bounds) =>
521522
((ICrossPlatformLayout)this).CrossPlatformArrange(bounds);

src/Core/src/Handlers/ScrollView/ScrollViewHandler.Android.cs

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,12 @@ protected override void ConnectHandler(MauiScrollView platformView)
2525
{
2626
base.ConnectHandler(platformView);
2727
platformView.ScrollChange += ScrollChange;
28-
platformView.CrossPlatformArrange = VirtualView.CrossPlatformArrange;
2928
}
3029

3130
protected override void DisconnectHandler(MauiScrollView platformView)
3231
{
3332
base.DisconnectHandler(platformView);
3433
platformView.ScrollChange -= ScrollChange;
35-
platformView.CrossPlatformArrange = null;
3634
}
3735

3836
public override Size GetDesiredSize(double widthConstraint, double heightConstraint)
@@ -234,7 +232,10 @@ static void InsertInsetView(IScrollViewHandler handler, IScrollView scrollView,
234232

235233
Size ICrossPlatformLayout.CrossPlatformMeasure(double widthConstraint, double heightConstraint)
236234
{
237-
var scrollView = VirtualView;
235+
if (VirtualView is not { } scrollView)
236+
{
237+
return Size.Zero;
238+
}
238239

239240
var padding = scrollView.Padding;
240241

@@ -243,31 +244,25 @@ Size ICrossPlatformLayout.CrossPlatformMeasure(double widthConstraint, double he
243244
return new Size(padding.HorizontalThickness, padding.VerticalThickness);
244245
}
245246

246-
// Exclude the padding while measuring the internal content ...
247-
var measurementWidth = widthConstraint - padding.HorizontalThickness;
248-
var measurementHeight = heightConstraint - padding.VerticalThickness;
249-
250-
var result = (scrollView as ICrossPlatformLayout).CrossPlatformMeasure(measurementWidth, measurementHeight);
251-
252-
// ... and add the padding back in to the final result
253-
var fullSize = new Size(result.Width + padding.HorizontalThickness, result.Height + padding.VerticalThickness);
247+
var scrollOrientation = scrollView.Orientation;
248+
var contentWidthConstraint = scrollOrientation is ScrollOrientation.Horizontal or ScrollOrientation.Both ? double.PositiveInfinity : widthConstraint;
249+
var contentHeightConstraint = scrollOrientation is ScrollOrientation.Vertical or ScrollOrientation.Both ? double.PositiveInfinity : heightConstraint;
250+
var contentSize = scrollView.MeasureContent(scrollView.Padding, contentWidthConstraint, contentHeightConstraint, !double.IsInfinity(contentWidthConstraint), !double.IsInfinity(contentHeightConstraint));
254251

255252
if (double.IsInfinity(widthConstraint))
256253
{
257-
widthConstraint = result.Width;
254+
widthConstraint = contentSize.Width;
258255
}
259256

260257
if (double.IsInfinity(heightConstraint))
261258
{
262-
heightConstraint = result.Height;
259+
heightConstraint = contentSize.Height;
263260
}
264261

265-
return fullSize.AdjustForFill(new Rect(0, 0, widthConstraint, heightConstraint), scrollView.PresentedContent);
262+
return contentSize.AdjustForFill(new Rect(0, 0, widthConstraint, heightConstraint), scrollView.PresentedContent);
266263
}
267264

268-
Size ICrossPlatformLayout.CrossPlatformArrange(Rect bounds)
269-
{
270-
return (VirtualView as ICrossPlatformLayout).CrossPlatformArrange(bounds);
271-
}
265+
Size ICrossPlatformLayout.CrossPlatformArrange(Rect bounds) =>
266+
(VirtualView as ICrossPlatformLayout)?.CrossPlatformArrange(bounds) ?? Size.Zero;
272267
}
273268
}

src/Core/src/Layouts/LayoutExtensions.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,37 @@ public static Size MeasureContent(this IContentView contentView, Thickness inset
167167
return new Size(contentSize.Width + inset.HorizontalThickness, contentSize.Height + inset.VerticalThickness);
168168
}
169169

170+
internal static Size MeasureContent(
171+
this IContentView contentView,
172+
Thickness inset,
173+
double widthConstraint,
174+
double heightConstraint,
175+
bool constrainPresentedContentWidthToExplicitDimsOnContentView,
176+
bool constrainPresentedContentHeightToExplicitDimsOnContentView)
177+
{
178+
var content = contentView.PresentedContent;
179+
180+
if (Dimension.IsExplicitSet(contentView.Width) && constrainPresentedContentWidthToExplicitDimsOnContentView)
181+
{
182+
widthConstraint = contentView.Width;
183+
}
184+
185+
if (Dimension.IsExplicitSet(contentView.Height) && constrainPresentedContentHeightToExplicitDimsOnContentView)
186+
{
187+
heightConstraint = contentView.Height;
188+
}
189+
190+
var contentSize = Size.Zero;
191+
192+
if (content != null)
193+
{
194+
contentSize = content.Measure(widthConstraint - inset.HorizontalThickness,
195+
heightConstraint - inset.VerticalThickness);
196+
}
197+
198+
return new Size(contentSize.Width + inset.HorizontalThickness, contentSize.Height + inset.VerticalThickness);
199+
}
200+
170201
public static void ArrangeContent(this IContentView contentView, Rect bounds)
171202
{
172203
if (contentView.PresentedContent == null)

src/Core/src/Platform/Android/MauiScrollView.cs

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,11 @@ public void SetOrientation(ScrollOrientation orientation)
9797
{
9898
if (_hScrollView == null)
9999
{
100-
_hScrollView = new MauiHorizontalScrollView(Context, this);
100+
_hScrollView = new MauiHorizontalScrollView(Context, this)
101+
{
102+
FillViewport = true
103+
};
104+
101105
_hScrollView.HorizontalFadingEdgeEnabled = HorizontalFadingEdgeEnabled;
102106
_hScrollView.SetFadingEdgeLength(HorizontalFadingEdgeLength);
103107
SetHorizontalScrollBarVisibility(_horizontalScrollVisibility);
@@ -229,15 +233,6 @@ protected override void OnLayout(bool changed, int left, int top, int right, int
229233
hScrollViewHeight = _isBidirectional ? Math.Max(hScrollViewHeight, scrollViewContentHeight) : hScrollViewHeight;
230234
_hScrollView.Layout(0, 0, hScrollViewWidth, hScrollViewHeight);
231235
}
232-
233-
if (CrossPlatformArrange == null)
234-
{
235-
return;
236-
}
237-
238-
var destination = Context!.ToCrossPlatformRectInReferenceFrame(left, top, right, bottom);
239-
240-
CrossPlatformArrange(destination);
241236
}
242237

243238
public void ScrollTo(int x, int y, bool instant, Action finished)
@@ -321,8 +316,6 @@ void IOnScrollChangeListener.OnScrollChange(NestedScrollView? v, int scrollX, in
321316
{
322317
OnScrollChanged(scrollX, scrollY, oldScrollX, oldScrollY);
323318
}
324-
325-
internal Func<Graphics.Rect, Graphics.Size>? CrossPlatformArrange { get; set; }
326319
}
327320

328321
internal class MauiHorizontalScrollView : HorizontalScrollView, IScrollBarView

0 commit comments

Comments
 (0)