Fixed - Grouped CollectionView items not rendered properly on Android, works on Windows#27847
Conversation
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
There was a problem hiding this comment.
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
Comments suppressed due to low confidence (1)
src/Controls/src/Core/Handlers/Items/Android/Adapters/StructuredItemsViewAdapter.cs:107
- The added condition to ensure only templated items (and not group header views) use the MeasureFirstItem sizing strategy fixes the rendering issue, but please verify that this change does not inadvertently affect header rendering in non-grouped scenarios.
if (ItemsView.ItemSizingStrategy == ItemSizingStrategy.MeasureFirstItem && templatedItemViewHolder.ItemViewType == ItemViewType.TemplatedItem)
|
/rebase |
69e4485 to
e891fb5
Compare
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
|
/rebase |
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
|
/azp run |
|
Azure Pipelines successfully started running 3 pipeline(s). |
|
/rebase |
|
Hi, at this moment, the measure 1st item doesnt work at all on Android on grouped CV. It will nice to have some performance boost in this scenario. I see that everything in this pr is detailed checked, but even if there will some problems isnt it better than current state? I would love to get those changes in Maui. Nice job with pr 🙌 |
Fix and test case modified
Fix and test case modified
06b0230 to
d58578b
Compare
|
/azp run maui-pr-uitests |
|
Azure Pipelines successfully started running 1 pipeline(s). |
🤖 AI Summary📊 Expand Full Review —
|
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #27847 | Skip MeasureFirstItem static-size reuse for structural grouped views (header/footer/group header/group footer), while still reusing the first measured data-item size for actual item templates. | ⏳ PENDING (Gate) | src/Controls/src/Core/Handlers/Items/Android/Adapters/StructuredItemsViewAdapter.cs, src/Controls/tests/TestCases.HostApp/Issues/Issue20855.cs, src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue20855.cs |
Current diff already reflects post-review adjustment for DataTemplateSelector scenarios. |
🚦 Gate — Test Verification
Gate Result: ✅ PASSED
Platform: android
Mode: Full Verification
- Tests FAIL without fix: ✅
- Tests PASS with fix: ✅
Notes:
- Initial verification attempt hit an Android deployment blocker (
ADB0010: Broken pipe) on the pass-with-fix leg. - One retry was run per workflow guidance, and full verification completed successfully on Android.
- Gate evidence from the isolated verification agent: the Issue20855 test failed against the broken baseline and passed with the PR fix restored.
🔧 Fix — Analysis & Comparison
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| 1 | try-fix (claude-opus-4.6) | Cache MeasureFirstItem sizes per ItemViewType instead of using a single shared cached size. |
✅ PASS | 1 file | Robust and optimization-friendly, but adds dictionary/state complexity beyond the immediate bug. |
| 2 | try-fix (claude-sonnet-4.6) | Keep the single cached size, but bind structural items with a no-op measure callback so only data items can populate the cache. | ✅ PASS | 1 file | Works, but introduces extra callback state solely to suppress writes into the shared cache. |
| 3 | try-fix (gpt-5.3-codex) | Invalidate the shared cached size after binding structural rows so following data rows must re-measure. | ❌ FAIL | 1 file | Visual regression remained; clearing after structural bind is too late / insufficient. |
| 4 | try-fix (gemini-3-pro-preview) | Fourth model first tried a call-site bypass (failed internally), then converged on the same structural-item exclusion used by the PR. | ✅ PASS | 1 file | Confirms the PR direction; not a distinct superior alternative. |
| 5 | try-fix (claude-sonnet-4.6, cross-pollination) | Introduce IsStructuralViewType virtual dispatch so each adapter layer owns the structural item types it defines. |
✅ PASS | 2 files | Cleaner layering than the inline check, but behavior is effectively the same as the PR and touches more files. |
| 6 | try-fix (gpt-5.3-codex, cross-pollination) | Store cached size together with ItemViewType, and only reuse it when the current holder type matches. |
✅ PASS | 1 file | Sound and type-aware, but still more stateful than needed for the bug at hand. |
| PR | PR #27847 | Skip static-size reuse for structural grouped view types (header/footer/group header/group footer). | ✅ PASSED (Gate) | 3 code files + snapshots | Small, direct fix already updated to avoid the earlier DataTemplateSelector regression concern. |
Cross-Pollination
| Model | Round | New Ideas? | Details |
|---|---|---|---|
| claude-opus-4.6 | 1 | No | NO NEW IDEAS |
| claude-sonnet-4.6 | 1 | Yes | Suggested moving structural-type knowledge into a helper akin to GetItemViewType; tested as candidate #5 and passed. |
| gpt-5.3-codex | 1 | Yes | Suggested type-tagging the shared cache; tested as candidate #6 and passed. |
| gemini-3-pro-preview | 1 | No | NO NEW IDEAS |
| claude-opus-4.6 | 2 | No | NO NEW IDEAS |
| claude-sonnet-4.6 | 2 | No | NO NEW IDEAS |
| gpt-5.3-codex | 2 | No | NO NEW IDEAS |
| gemini-3-pro-preview | 2 | No | NO NEW IDEAS |
Exhausted: Yes
Selected Fix: PR #27847 — It is the simplest passing solution, touches the fewest production concepts, and already incorporates the post-review refinement that avoids regressing DataTemplateSelector-backed item templates.
📋 Report — Final Recommendation
✅ Final Recommendation: APPROVE
Phase Status
| Phase | Status | Notes |
|---|---|---|
| Pre-Flight | ✅ COMPLETE | Linked issues and review-thread history captured, including the later DataTemplateSelector concern and follow-up refinement. |
| Gate | ✅ PASSED | Android full verification: test failed without fix and passed with fix after one transient ADB retry. |
| Try-Fix | ✅ COMPLETE | 6 completed alternative candidates evaluated (5 passing, 1 failing), plus one partial/abandoned internal call-site attempt during the Gemini run; design space exhausted after 2 cross-pollination rounds. |
| Report | ✅ COMPLETE |
Summary
PR #27847 fixes the Android grouped CollectionView MeasureFirstItem bug by preventing structural grouped rows from participating in the shared static-size reuse path. The added Issue20855 UI test correctly catches the bug on Android, failing against the broken baseline and passing with the fix restored. Try-fix exploration found several viable alternatives, but none was clearly better than the PR's current approach.
Root Cause
StructuredItemsViewAdapter reused a single cached measurement for MeasureFirstItem. In grouped scenarios, a structural row such as a group header could be measured first, and its dimensions would then be incorrectly reused for later data items. That polluted measurement causes the actual item template rows to collapse or render with incorrect heights on Android.
Fix Quality
The PR fix is correct, small, and easy to reason about. It directly prevents structural item types (Header, Footer, GroupHeader, GroupFooter) from feeding or consuming the cached data-item size while preserving the intended optimization for real item templates. A prior review concern about DataTemplateSelector compatibility has already been addressed by broadening the condition from a single TemplatedItem equality check to structural-item exclusion, which matches the best result from the review exploration.
…, works on Windows (#27847) ### Issue Details: ItemsView not visible when Grouping is enabled and ItemSizingStrategy property set to MeasureFirstItem for CollectionView in android platform. ### Root Cause: The ItemSizingStrategy property is set to MeasureFirstItem for the CollectionView in the sample. As a result, the CollectionView calculates the size of the first item (which is a group header template) and applies this size to all subsequent templated items during binding. When the second item (defined by the ItemTemplate) is measured, it uses the size of the first item. However, during the layout phase, the second item respects the height request specified in the DataTemplate and is laid out according to that height. This mismatch between the measured size and the layout size for the ItemTemplate results in incorrect dimensions, causing the item to not display properly in the view. ### Description of Change: I calculated the size from the ItemTemplate instead of the group header template or any other template by adding a condition to check if templatedItemViewHolder.ItemViewType == ItemViewType.TemplatedItem. This allows the calculated size from the first ItemTemplate to be reused for all subsequent ItemTemplate items. As a result, the correct dimensions are measured and laid out according to the calculated size. **Tested the behavior in the following platforms.** - [x] Android - [x] Windows - [x] iOS - [x] Mac ### Reference: N/A ### Issues Fixed: Fixes #20855 Fixes #29191 Fixes #32578 ### Screenshots | Before | After | |---------|--------| | <img width="259" alt="Screenshot 2025-02-17 at 7 58 19 PM" src="https://github.com/user-attachments/assets/f3ff0dba-39cd-4d19-aac4-2b9db1e82995" /> | <img width="259" alt="Screenshot 2025-02-17 at 7 52 33 PM" src="https://github.com/user-attachments/assets/1a1e446d-be9f-44ec-8742-774d969ab7c8" /> |
Issue Details:
ItemsView not visible when Grouping is enabled and ItemSizingStrategy property set to MeasureFirstItem for CollectionView in android platform.
Root Cause:
The ItemSizingStrategy property is set to MeasureFirstItem for the CollectionView in the sample. As a result, the CollectionView calculates the size of the first item (which is a group header template) and applies this size to all subsequent templated items during binding. When the second item (defined by the ItemTemplate) is measured, it uses the size of the first item. However, during the layout phase, the second item respects the height request specified in the DataTemplate and is laid out according to that height. This mismatch between the measured size and the layout size for the ItemTemplate results in incorrect dimensions, causing the item to not display properly in the view.
Description of Change:
I calculated the size from the ItemTemplate instead of the group header template or any other template by adding a condition to check if templatedItemViewHolder.ItemViewType == ItemViewType.TemplatedItem. This allows the calculated size from the first ItemTemplate to be reused for all subsequent ItemTemplate items. As a result, the correct dimensions are measured and laid out according to the calculated size.
Tested the behavior in the following platforms.
Reference:
N/A
Issues Fixed:
Fixes #20855
Fixes #29191
Fixes #32578
Screenshots