Skip to content

Commit 51a1d77

Browse files
CopilotSuthiYuvaraj
andcommitted
Fix ContentView Width availability during CollectionView scrolling scenarios
Co-authored-by: SuthiYuvaraj <[email protected]>
1 parent d7343f5 commit 51a1d77

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

src/Core/src/Platform/Android/ContentViewGroup.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,19 @@ protected override void OnLayout(bool changed, int left, int top, int right, int
109109
var destination = _context.ToCrossPlatformRectInReferenceFrame(left, top, right, bottom);
110110

111111
CrossPlatformArrange(destination);
112+
113+
// Ensure the ContentView's Frame is updated with the final layout bounds
114+
// This is especially important during scrolling scenarios where the Frame
115+
// might be reset or updated after the measure pass
116+
if (CrossPlatformLayout is IView contentView)
117+
{
118+
var currentFrame = contentView.Frame;
119+
var newFrame = destination;
120+
if (currentFrame != newFrame)
121+
{
122+
contentView.Frame = newFrame;
123+
}
124+
}
112125
}
113126

114127
internal IBorderStroke? Clip

src/Core/tests/DeviceTests/Handlers/ContentView/ContentViewTests.cs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,55 @@ public async Task ContentViewWidthAvailableToChildrenDuringLayout()
7878
Assert.Equal(200, result.ContentViewWidth, 0);
7979
Assert.Equal(200, result.ChildRecordedWidth, 0);
8080
}
81+
82+
[Fact]
83+
public async Task ContentViewWidthAvailableToChildrenDuringScrolling()
84+
{
85+
var contentView = new ContentViewStub();
86+
var childView = new TestChildView();
87+
88+
contentView.Content = childView;
89+
contentView.WidthRequest = 200;
90+
contentView.HeightRequest = 100;
91+
92+
var contentViewHandler = await CreateHandlerAsync(contentView);
93+
94+
// Simulate multiple layout passes that occur during scrolling in CollectionView
95+
var result = await InvokeOnMainThreadAsync(() =>
96+
{
97+
// Initial layout
98+
contentView.Measure(200, 100);
99+
contentView.Arrange(new Graphics.Rect(0, 0, 200, 100));
100+
101+
// Simulate scrolling - multiple measure/arrange cycles with different positions
102+
// This simulates what happens when CollectionView recycles and repositions items during scrolling
103+
for (int i = 0; i < 3; i++)
104+
{
105+
// Reset the child's recorded width to test each cycle
106+
childView.RecordedParentWidth = -1;
107+
108+
// Simulate different positions during scrolling
109+
var yOffset = i * 10;
110+
contentView.Measure(200, 100);
111+
contentView.Arrange(new Graphics.Rect(0, yOffset, 200, 100 + yOffset));
112+
113+
// Child should have access to parent width even during position changes
114+
if (childView.RecordedParentWidth <= 0)
115+
{
116+
return new { Success = false, ContentViewWidth = contentView.Width, ChildRecordedWidth = childView.RecordedParentWidth, FailedAtIteration = i };
117+
}
118+
}
119+
120+
return new { Success = true, ContentViewWidth = contentView.Width, ChildRecordedWidth = childView.RecordedParentWidth, FailedAtIteration = -1 };
121+
});
122+
123+
// The child should have access to the parent's width during all scrolling scenarios
124+
Assert.True(result.Success, $"Child failed to access parent width during scrolling at iteration {result.FailedAtIteration}");
125+
Assert.True(result.ContentViewWidth > 0, "ContentView Width should be greater than 0");
126+
Assert.True(result.ChildRecordedWidth > 0, "Child should have recorded a positive parent width during scrolling");
127+
Assert.Equal(200, result.ContentViewWidth, 0);
128+
Assert.Equal(200, result.ChildRecordedWidth, 0);
129+
}
81130
}
82131

83132
public class TestChildView : IView

0 commit comments

Comments
 (0)