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

Add ScrollToItem #15

Merged
merged 2 commits into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Sample/VirtualListViewSample/ObservableCollectionPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
xmlns:local="clr-namespace:VirtualListViewSample"
xmlns:vlv="clr-namespace:Microsoft.Maui.Controls;assembly=VirtualListView"
Title="ObservableCollectionPage">
<Grid RowDefinitions="*,Auto" ColumnDefinitions="*,Auto" Padding="20">
<Grid RowDefinitions="*,Auto" ColumnDefinitions="*,Auto,Auto" Padding="20">
<vlv:VirtualListView
Grid.Row="0"
Grid.Column="0" Grid.ColumnSpan="2"
Grid.Column="0" Grid.ColumnSpan="3"
x:Name="vlv"
OnSelectedItemsChanged="vlv_SelectedItemsChanged"
SelectionMode="Multiple">
Expand Down Expand Up @@ -39,5 +39,6 @@

<Entry x:Name="entryItem" Grid.Row="1" Grid.Column="0" Placeholder="Item" />
<Button Grid.Row="1" Grid.Column="1" Text="Add" Clicked="Button_Clicked" />
<Button Grid.Row="1" Grid.Column="2" Text="Scroll To" Clicked="ScrollTo_Clicked" />
</Grid>
</ContentPage>
14 changes: 13 additions & 1 deletion Sample/VirtualListViewSample/ObservableCollectionPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public ObservableCollectionPage()

Adapter = new ObservableCollectionAdapter<string>(Items);

for (int i = 0; i < 10; i++)
for (int i = 0; i < 100; i++)
{
Items.Add($"Item: {i}");
}
Expand Down Expand Up @@ -61,4 +61,16 @@ private void vlv_SelectedItemsChanged(object sender, SelectedItemsChangedEventAr
Items.Remove(item);
}
}

private void ScrollTo_Clicked(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(entryItem.Text))
{
var item = Items.FirstOrDefault(i => i.Equals(entryItem.Text, StringComparison.InvariantCultureIgnoreCase));

var itemIndex = Items.IndexOf(item);

vlv.ScrollToItem(new ItemPosition(0, itemIndex), true);
}
}
}
16 changes: 14 additions & 2 deletions VirtualListView/Apple/VirtualListViewHandler.ios.maccatalyst.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ protected override void ConnectHandler(UICollectionView nativeView)
VirtualView?.Scrolled(x, y));

nativeView.DataSource = dataSource;
nativeView.Delegate = cvdelegate;
nativeView.Delegate = cvdelegate;

nativeView.ReloadData();
}
Expand Down Expand Up @@ -123,6 +123,18 @@ public static void MapSelectionMode(VirtualListViewHandler handler, IVirtualList
public static void MapInvalidateData(VirtualListViewHandler handler, IVirtualListView virtualListView, object? parameter)
=> handler?.InvalidateData();

void PlatformScrollToItem(ItemPosition itemPosition, bool animated)
{
var realIndex = PositionalViewSelector?.GetPosition(itemPosition.SectionIndex, itemPosition.ItemIndex) ?? -1;

if (realIndex < 0)
return;

var indexPath = NSIndexPath.FromItemSection(realIndex, 0);

PlatformView.ScrollToItem(indexPath, UICollectionViewScrollPosition.Top, animated);
}

void PlatformUpdateItemSelection(ItemPosition itemPosition, bool selected)
{
var realIndex = PositionalViewSelector?.GetPosition(itemPosition.SectionIndex, itemPosition.ItemIndex) ?? -1;
Expand All @@ -134,7 +146,7 @@ void PlatformUpdateItemSelection(ItemPosition itemPosition, bool selected)

if (cell is CvCell cvcell)
{
PlatformView.InvokeOnMainThread(() =>
PlatformView.InvokeOnMainThread(() =>
{
cvcell.UpdateSelected(selected);
});
Expand Down
3 changes: 3 additions & 0 deletions VirtualListView/Controls/VirtualListView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,9 @@ public void ClearSelectedItems()
SelectedItem = null;
}

public void ScrollToItem(ItemPosition itemPosition, bool animated)
=> Handler?.Invoke(nameof(ScrollToItem), new object[] { itemPosition, animated });

public bool SectionHasHeader(int sectionIndex)
=> SectionHeaderTemplateSelector != null || SectionHeaderTemplate != null;

Expand Down
2 changes: 2 additions & 0 deletions VirtualListView/IVirtualListView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ public interface IVirtualListView : IView
void DeselectItem(ItemPosition path);

void ClearSelectedItems();

void ScrollToItem(ItemPosition path, bool animated);
}

public enum ListOrientation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@ public void InvalidateData()
adapter?.NotifyDataSetChanged();
}

void PlatformScrollToItem(ItemPosition itemPosition, bool animated)
{
var position = PositionalViewSelector.GetPosition(itemPosition.SectionIndex, itemPosition.ItemIndex);

recyclerView.ScrollToPosition(position);
}

public static void MapHeader(VirtualListViewHandler handler, IVirtualListView virtualListView)
=> handler.InvalidateData();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using WVisibility = Microsoft.UI.Xaml.Visibility;
using WFrameworkElement = Microsoft.UI.Xaml.FrameworkElement;
using Microsoft.Maui.Platform;
using Microsoft.UI.Xaml;

namespace Microsoft.Maui;

Expand Down Expand Up @@ -86,6 +87,15 @@ public void InvalidateData()
UpdateEmptyViewVisibility();
}

void PlatformScrollToItem(ItemPosition itemPosition, bool animated)
{
var position = PositionalViewSelector.GetPosition(itemPosition.SectionIndex, itemPosition.ItemIndex);

var elem = itemsRepeater.GetOrCreateElement(position);

elem.StartBringIntoView(new BringIntoViewOptions() { AnimationDesired = animated });
}

public static void MapHeader(VirtualListViewHandler handler, IVirtualListView virtualListView)
=> handler?.InvalidateData();

Expand Down
20 changes: 20 additions & 0 deletions VirtualListView/VirtualListViewHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,28 @@ public partial class VirtualListViewHandler

public static CommandMapper<IVirtualListView, VirtualListViewHandler> CommandMapper = new(ViewCommandMapper)
{
[nameof(IVirtualListView.ScrollToItem)] = MapScrollToItem,
};

public static void MapScrollToItem(VirtualListViewHandler handler, IVirtualListView view, object parameter)
{
if (parameter is ItemPosition itemPosition)
{
handler.PlatformScrollToItem(itemPosition, true);
}
else if (parameter is object[] parameters)
{
if (parameters?[0] is ItemPosition p)
{
var animated = true;
if (parameters?[1] is bool a)
animated = a;

handler.PlatformScrollToItem(p, animated);
}
}
}

public VirtualListViewHandler() : base(ViewMapper, CommandMapper)
{

Expand Down