diff --git a/src/Controls/src/Core/Handlers/Items/Android/MauiRecyclerView.cs b/src/Controls/src/Core/Handlers/Items/Android/MauiRecyclerView.cs index adebfc16e999..2c2a75a63074 100644 --- a/src/Controls/src/Core/Handlers/Items/Android/MauiRecyclerView.cs +++ b/src/Controls/src/Core/Handlers/Items/Android/MauiRecyclerView.cs @@ -425,9 +425,9 @@ protected virtual int DetermineTargetPosition(ScrollToRequestEventArgs args) if (args.Mode == ScrollToMode.Position) { // Do not use `IGroupableItemsViewSource` since `UngroupedItemsSource` also implements that interface - if (ItemsViewAdapter.ItemsSource is UngroupedItemsSource) + if (ItemsViewAdapter.ItemsSource is UngroupedItemsSource ungroupedSource) { - return args.Index; + return ungroupedSource.HasHeader ? args.Index + 1 : args.Index; } else if (ItemsViewAdapter.ItemsSource is IGroupableItemsViewSource groupItemSource) { diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue18389.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue18389.cs new file mode 100644 index 000000000000..3d695c1fe85a --- /dev/null +++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue18389.cs @@ -0,0 +1,113 @@ +using System.Collections.ObjectModel; + +namespace Maui.Controls.Sample.Issues; + +[Issue(IssueTracker.Github, 18389, "Incorrect scroll position when scrolling to an item with header in CollectionView", PlatformAffected.Android)] +public class Issue18389 : ContentPage +{ + ObservableCollection _items; + CollectionView2 _collectionView; + public Issue18389() + { + GenerateItems(); + + Grid mainGrid = new Grid + { + Padding = new Thickness(20), + RowSpacing = 10, + RowDefinitions = + { + new RowDefinition { Height = GridLength.Auto }, + new RowDefinition { Height = GridLength.Auto }, + new RowDefinition { Height = GridLength.Auto }, + new RowDefinition { Height = GridLength.Star } + } + }; + + Button scrollToIndexButton = new Button + { + AutomationId = "Issue18389_ScrollToBtn", + Text = "Click me to scroll to index Count - 1!" + }; + scrollToIndexButton.Clicked += ScrollToLastItem; + + Button removeHeaderButton = new Button + { + AutomationId = "Issue18389_RemoveHeaderBtn", + Text = "Remove Header" + }; + removeHeaderButton.Clicked += RemoveHeader; + + Button resetCollectionViewButton = new Button + { + AutomationId = "Issue18389_ResetBtn", + Text = "Reset CollectionView to 0,0" + }; + resetCollectionViewButton.Clicked += ResetCollectionView; + + mainGrid.Add(scrollToIndexButton, 0, 0); + mainGrid.Add(resetCollectionViewButton, 0, 1); + mainGrid.Add(removeHeaderButton, 0, 2); + + _collectionView = new CollectionView2 + { + ItemsSource = _items, + ItemTemplate = new DataTemplate(() => + { + Label label = new Label + { + FontSize = 40 + }; + label.SetBinding(Label.TextProperty, "."); + label.SetBinding(Label.AutomationIdProperty, "."); + + return label; + }), + Header = new Label + { + Text = "Header", + BackgroundColor = Colors.Black, + TextColor = Colors.White, + FontSize = 50, + FontFamily = "Bold" + }, + Footer = new Label + { + Text = "Footer", + BackgroundColor = Colors.Black, + TextColor = Colors.White, + FontSize = 50, + FontFamily = "Bold" + }, + }; + + mainGrid.Add(_collectionView, 0, 3); + + Content = mainGrid; + } + + void GenerateItems() + { + _items = new ObservableCollection(); + + for (int i = 1; i <= 20; i++) + { + _items.Add($"Item {i}"); + } + } + + void ScrollToLastItem(object sender, EventArgs e) + { + _collectionView.ScrollTo(_items.Count - 1, -1, ScrollToPosition.End); + } + + void RemoveHeader(object sender, EventArgs e) + { + _collectionView.Header = null; + } + + void ResetCollectionView(object sender, EventArgs e) + { + _collectionView.ScrollTo(0); + } +} \ No newline at end of file diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue18389.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue18389.cs new file mode 100644 index 000000000000..6cb39acc62e7 --- /dev/null +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue18389.cs @@ -0,0 +1,35 @@ +using NUnit.Framework; +using UITest.Appium; +using UITest.Core; + +namespace Microsoft.Maui.TestCases.Tests.Issues; + +public class Issue18389 : _IssuesUITest +{ + public Issue18389(TestDevice device) : base(device) + { + } + + public override string Issue => "Incorrect scroll position when scrolling to an item with header in CollectionView"; + + [Test] + [Category(UITestCategories.CollectionView)] + public void VerifyScrollToIndexWithHeader() + { + App.WaitForElement("Issue18389_ScrollToBtn"); + App.Tap("Issue18389_ScrollToBtn"); + + App.WaitForElement("Item 20"); + + App.WaitForElement("Issue18389_ResetBtn"); + App.Tap("Issue18389_ResetBtn"); + + App.WaitForElement("Item 1"); + + App.WaitForElement("Issue18389_RemoveHeaderBtn"); + App.Tap("Issue18389_RemoveHeaderBtn"); + + App.Tap("Issue18389_ScrollToBtn"); + App.WaitForElement("Item 20"); + } +} \ No newline at end of file