Skip to content

Commit

Permalink
Merge pull request #46 from Redth/dev/visible-item-indices
Browse files Browse the repository at this point in the history
Implement FindVisiblePositions()
  • Loading branch information
Redth committed Jun 7, 2024
2 parents 79e5718 + 3bc5a85 commit 8dec21b
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 1 deletion.
13 changes: 13 additions & 0 deletions VirtualListView/Apple/VirtualListViewHandler.ios.maccatalyst.cs
Original file line number Diff line number Diff line change
Expand Up @@ -255,4 +255,17 @@ public void InvalidateData()
});

}

public IReadOnlyList<IPositionInfo> FindVisiblePositions()
{
var positions = new List<PositionInfo>();

foreach (var cell in PlatformView.VisibleCells)
{
if (cell is CvCell cvCell)
positions.Add(cvCell.PositionInfo);
}

return positions;
}
}
8 changes: 8 additions & 0 deletions VirtualListView/Controls/VirtualListView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -402,4 +402,12 @@ public void ViewAttached(PositionInfo position, IView view)
void RaiseSelectedItemsChanged(ItemPosition[] previousSelection, ItemPosition[] newSelection)
=> this.OnSelectedItemsChanged?.Invoke(this, new SelectedItemsChangedEventArgs(previousSelection, newSelection));

public IReadOnlyList<IPositionInfo> FindVisiblePositions()
{
#if ANDROID || IOS || MACCATALYST || WINDOWS
if (Handler is IVirtualListViewHandler handler)
return handler.FindVisiblePositions();
#endif
return [];
}
}
2 changes: 2 additions & 0 deletions VirtualListView/IVirtualListView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ public interface IVirtualListView : IView
void ClearSelectedItems();

void ScrollToItem(ItemPosition path, bool animated);

IReadOnlyList<IPositionInfo> FindVisiblePositions();
}

public enum ListOrientation
Expand Down
8 changes: 8 additions & 0 deletions VirtualListView/IVirtualListViewHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Microsoft.Maui;

public interface IVirtualListViewHandler
{
#if ANDROID || IOS || MACCATALYST || WINDOWS
IReadOnlyList<IPositionInfo> FindVisiblePositions();
#endif
}
Original file line number Diff line number Diff line change
Expand Up @@ -195,4 +195,19 @@ void UpdateHorizontalScrollbarVisibility(ScrollBarVisibility scrollBarVisibility

recyclerView.HorizontalScrollBarEnabled = newHorizontalScrollVisiblility == ScrollBarVisibility.Always;
}

public IReadOnlyList<IPositionInfo> FindVisiblePositions()
{
var positions = new List<IPositionInfo>();

var firstVisibleItemPosition = layoutManager.FindFirstVisibleItemPosition();
var lastVisibleItemPosition = layoutManager.FindLastVisibleItemPosition();

for (var p = firstVisibleItemPosition; p <= lastVisibleItemPosition; p++)
{
positions.Add(PositionalViewSelector.GetInfo(p));
}

return positions;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
using WVisibility = Microsoft.UI.Xaml.Visibility;
using WFrameworkElement = Microsoft.UI.Xaml.FrameworkElement;
using WScrollBarVisibility = Microsoft.UI.Xaml.Controls.ScrollBarVisibility;
using WRect = Windows.Foundation.Rect;
using Microsoft.Maui.Platform;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Media;

namespace Microsoft.Maui;

Expand Down Expand Up @@ -187,4 +189,37 @@ void UpdateHorizontalScrollbarVisibility(ScrollBarVisibility scrollBarVisibility
_ => WScrollBarVisibility.Auto
};
}

public IReadOnlyList<IPositionInfo> FindVisiblePositions()
{
var positions = new List<PositionInfo>();

// This gets us all the direct children of our repeater which should be IrElementContainers
// The items will not all be visible, since virtualizing causes items to get setup out of view
// before being displayed. We need to check if they are actually visible.
var childrenCount = VisualTreeHelper.GetChildrenCount(itemsRepeater);

for (int i = 0; i < childrenCount; i++)
{
// See if the child is an IrElementContainer
if (VisualTreeHelper.GetChild(itemsRepeater, i) is IrElementContainer irElementContainer)
{
// Is the item actually visible?
if (VisibilityHitTest(irElementContainer, itemsRepeater))
positions.Add(irElementContainer.PositionInfo);
}
}

return positions;
}

static bool VisibilityHitTest(IrElementContainer element, FrameworkElement container)
{
var bounds = element.TransformToVisual(container).TransformBounds(new WRect(0.0, 0.0, element.ActualWidth, element.ActualHeight));

return bounds.Left < container.ActualWidth
&& bounds.Top < container.ActualHeight
&& bounds.Right > 0
&& bounds.Bottom > 0;
}
}
2 changes: 1 addition & 1 deletion VirtualListView/VirtualListViewHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Microsoft.Maui;

public partial class VirtualListViewHandler
public partial class VirtualListViewHandler : IVirtualListViewHandler
{
#if ANDROID || IOS || MACCATALYST || WINDOWS
public static new IPropertyMapper<IVirtualListView, VirtualListViewHandler> ViewMapper = new PropertyMapper<IVirtualListView, VirtualListViewHandler>(Handlers.ViewHandler.ViewMapper)
Expand Down

0 comments on commit 8dec21b

Please sign in to comment.