Nalu.Maui.VirtualScroll: high-performance virtualized list (RecyclerView/UICollectionView). Use when building lists, carousels, sectioned data, pull-to-refresh, drag-and-drop reorder, or replacing MAUI CollectionView for performance.
High-performance virtualized scrolling (Android RecyclerView, iOS UICollectionView). Replaces MAUI CollectionView with dynamic item sizing, headers/footers, sections, carousel, pull-to-refresh, and drag-and-drop.
IVirtualScrollAdapter (factory methods), not raw ObservableCollection binding.builder.UseNaluVirtualScroll();
VirtualScroll.CreateObservableCollectionAdapter(items) or ; for static data: or with sections.CreateObservableCollectionAdapter(sections, s => s.Items)CreateStaticCollectionAdapter(items)Wrap item content in nalu:ViewBox for best performance.
<nalu:VirtualScroll ItemsSource="{Binding Adapter}">
<nalu:VirtualScroll.ItemTemplate>
<DataTemplate x:DataType="models:MyItem">
<nalu:ViewBox>
<Label Text="{Binding Name}" Padding="16" />
</nalu:ViewBox>
</DataTemplate>
</nalu:VirtualScroll.ItemTemplate>
</nalu:VirtualScroll>
DataTemplateSelector for heterogeneous item types (e.g. different templates by item type). Set the selector as the template value; use sparingly—many templates can reduce recycling efficiency.<nalu:VirtualScroll.ItemTemplate>
<local:MyItemTemplateSelector
TextTemplate="{StaticResource TextItemTemplate}"
ImageTemplate="{StaticResource ImageItemTemplate}" />
</nalu:VirtualScroll.ItemTemplate>
{nalu:VerticalVirtualScrollLayout} (default), {nalu:HorizontalVirtualScrollLayout}.HorizontalCarouselVirtualScrollLayout, VerticalCarouselVirtualScrollLayout; bind CarouselVirtualScrollLayout.CurrentRange to int or VirtualScrollRange for current index.EstimatedItemSize, EstimatedHeaderSize, EstimatedSectionHeaderSize, etc. on layout for iOS.ScrollToPosition (MakeVisible, Start, Center, End) and animated.VirtualScrollScrolledEventArgs (ScrollX/Y, ScrollPercentageY, RemainingScrollY, etc.). Use for progress/infinite scroll; do not call GetVisibleItemsRange() inside scroll handlers (expensive).See Scrolling for visible range and infinite-scroll patterns.
IsRefreshEnabled="True", RefreshCommand, IsRefreshing, RefreshAccentColor. RefreshCommand receives a completion callback—invoke it when done: completionCallback(); in a RelayCommand or args.Complete() with OnRefresh event.
Bind DragHandler to the same adapter as ItemsSource (adapters implement IReorderableVirtualScrollAdapter). Only data items are reorderable; headers/footers are not. See Drag & Drop for custom behavior.
<nalu:VirtualScroll ItemsSource="{Binding Adapter}" DragHandler="{Binding Adapter}">
nalu:ViewBox in item templates.ObservableCollection directly.ObservableRangeCollection<T> for bulk updates.GetVisibleItemsRange() in scroll handlers; use ScrollPercentageY or RemainingScrollY for infinite scroll.IVirtualScrollAdapter (e.g. from factory); binding ObservableCollection directly throws in AOT.