Scrolling in Xamarin ListView (SfListView)

21 May 202115 minutes to read

Programmatic scrolling

Scrolling to row index

The SfListView allows programmatically scrolling based on the index by using the ScrollToRowIndex method for both linear and grid layouts. It also enables and disables the scrolling animation when changing the view. By default, the scrolling will be animated.

You can set position of item in view while scrolling by passing ScrollToPosition to ScrollToRowIndex method. Below are four different types of positions:

  • MakeVisible: Scrolls a specific item to make visible in the view. If the item is already in view, scrolling will not occur.
  • Start: Scrolls a specific item to be positioned at the begin of the view.
  • End: Scrolls a specific item to be positioned at the end of the view.
  • Center: Scrolls a specific item to be positioned at the center of the view.

You can also scroll to specified data in SfListView using the ScrollTo method.

int index = listView.DataSource.DisplayItems.IndexOf(viewModel.Customers[2]); 
// Programmatic scrolling based on the item index.
listView.LayoutManager.ScrollToRowIndex(index, Syncfusion.ListView.XForms.ScrollToPosition.Center, true); 
// Programmatic scrolling based on the item data.
listView.ScrollTo(ViewModel.Customers[index], Syncfusion.ListView.XForms.ScrollToPosition.Center, true);

NOTE

If grouping is enabled, get the desired row index by passing the underlying data in the DisplayItems.IndexOf method.

int index = listView.DataSource.DisplayItems.IndexOf(viewModel.Customers[2]); 
listView.LayoutManager.ScrollToRowIndex(index, true);

Limitations

  • When AutoFitMode is Height or grouping is enabled, the scroll animation will be disabled by default in Android and iOS platforms.
  • If the ScrollToRowIndex method is called when loading the SfListView, set disableAnimation to true to scroll to the appropriate row index, or else view does not scrolled in Android.
  • If the ScrollToRowIndex method is applied to a particular item index while the item is in Grouping or AutoFitMode, the particular item will get displayed in view but not in the exact position when the ScrollToPosition property is set as MakeVisible or Center for first time.
  • In UWP platform, when you hover and scroll the inner listview, the outer listview will not be scrolled by default. To overcome this, set the InputTransparent to True for the parent element loaded in the ItemTemplate. If you set InputTransparent, then the inner listview scroll will not work. This is the default behavior of the ListView.
  • The programmatic scrolling is not supported when the QueryItemSize event is handled.

Scrollbar visibility

The SfListView provides an option to enable or disable the Scrollbar visibility by using the IsScrollBarVisible property. By default, the value will be true.

NOTE

Due to some restrictions in native ScrollView renderer in Xamarin.Forms, you cannot change the IsScrollBarVisible value at runtime. It can be defined only when initializing the SfListView.

<syncfusion:SfListView x:Name="listView" IsScrollBarVisible="False" />
listView.IsScrollBarVisible = false;

ListView with full height

The SfListView will load all of its items by setting the IsScrollingEnabled property to false.

<syncfusion:SfListView x:Name="listView" IsScrollingEnabled="False" />
listView.IsScrollingEnabled = false;

NOTE

ListView’s scrolling will not be enabled when IsScrollingEnabled is false. To enable scrolling, load ListView inside ScrollView.

Identifying scroll state changes

The SfListView will notify the scrolling state changes by using the ScrollStateChanged event.

The following states will be notified using the ScrollState property in the event argument.

  • Dragging: Specifies that SfListView is currently being dragged in the view.
  • Fling: Specifies that fling action is performed on the SfListView.
  • Idle: Specifies that SfListView is not currently scrolling.
  • Programmatic: Specifies that scrolling is performed by using ScrollTo or ScrollToRowIndex method.
listView.ScrollStateChanged += ListView_ScrollStateChanged;
private void ListView_ScrollStateChanged(object sender, ScrollStateChangedEventArgs e)
{
   if (e.ScrollState == ScrollState.Idle)
   {
      DisplayAlert("ScrollState", "Scrolling has stopped", "OK");
   }
}

Identify when end of the list is reached on scrolling

The SfListView allows notifying when scrolling using the Changed event of ScrollAxisBase in VisualContainer of the SfListView. By using this event, you can find whether reached the last item in the list in the SfListView based on the LastBodyVisibleLineIndex property and underlying collection count.

using Syncfusion.ListView.XForms.Control.Helpers;
public partial class MainPage : ContentPage
{
    VisualContainer visualContainer;
    bool isAlertShown = false;

    public MainPage()
    {
        InitializeComponent();
        visualContainer = listView.GetVisualContainer();
        visualContainer.ScrollRows.Changed += ScrollRows_Changed;
    }

    ///<summary>
    ///To notify when end reached
    ///</summary>
    private void ScrollRows_Changed(object sender, ScrollChangedEventArgs e)
    {
        var lastIndex = visualContainer.ScrollRows.LastBodyVisibleLineIndex;

        //To include header if used
        var header = (listView.HeaderTemplate != null && !listView.IsStickyHeader) ? 1 : 0;

        //To include footer if used
        var footer = (listView.FooterTemplate != null && !listView.IsStickyFooter) ? 1 : 0;
        var totalItems = listView.DataSource.DisplayItems.Count + header + footer;

        if ((lastIndex == totalItems - 1))
        {
            if (!isAlertShown)
            {
                DisplayAlert("Alert", "End of list reached...", "Ok");
                isAlertShown = true;
            }
        }
        else
            isAlertShown = false;
    }
}

You can get the item elements to hold by a scrollable visual container using the GetVisualContainer method. It is a helper method of SfListView control.

using Syncfusion.ListView.XForms.Control.Helpers;
public partial class MainPage : ContentPage
{
    VisualContainer visualContainer;
	
    public MainPage()
    {
        InitializeComponent();
        visualContainer = listView.GetVisualContainer();
	}
}

Download the entire source code from GitHub here.

Maintain the scroll position while updating ItemsSource at runtime

The SfListView have scrolled to top automatically when changing the ItemsSource at runtime. However, you can maintain the same scrolled position by using the ScrollY value of ExtendedScrollView from the VisualContainer. After changing the ItemsSource, you can pass the ScrollY value to ScrollTo method of SfListView and scroll back to the same position.

For Horizontal orientation, use the ScrollX value of ExtendedScrollView.

By using Reflection, get the value of ScrollOwner from VisualContainer and use it.

using Syncfusion.ListView.XForms.Control.Helpers;
public partial class MainPage : ContentPage
{
    ExtendedScrollView scrollView;

    public MainPage()
    {
        InitializeComponent();
        scrollView = listView.GetScrollView();
    }

    private void ChangeItemsSource_Clicked(object sender, EventArgs e)
    {
        var viewModel = new ContactsViewModel();
        listView.ItemsSource = viewModel.EmployeeInfo;
        listView.ScrollTo(scrollView.ScrollY);
    }
}

You can get the scroll view by using the GetScrollView method. It is a helper method to get the Syncfusion.ListView.XForms.ExtendedScrollView class.

using Syncfusion.ListView.XForms.Control.Helpers;
public partial class MainPage : ContentPage
{
    ExtendedScrollView scrollView;

    public MainPage()
    {
        InitializeComponent();
        scrollView = listView.GetScrollView();
    }
}

Download the entire source code from GitHub here.

How to handle the recycle of the ListView Items

By default, the SfListview reuses items on scrolling and source collection change. You can skip the reusing while scrolling by setting the ListViewCachingStrategy property to CreateNewTemplate for the ListView. It creates a new element for every data in the ItemsSource. The default value is RecycleTemplate where the data template gets reused while the data object associated with the listview item gets changed.

<syncfusion:SfListView x:Name="listView" ListViewCachingStrategy="CreateNewTemplate" />
listView.ListViewCachingStrategy = ListViewCachingStrategy.CreateNewTemplate;

You can skip the reusing of list items on the ItemsSourcePropertyChanged by setting the ItemsSourceChangeCachingStrategy property to ClearItems for the ListView. Here, the existing ListView items will be cleared and create a new list of items when the ItemsSource changed. The default value is RecycleItems where the listView items will be recycled in the ItemsSource changes.

<syncfusion:SfListView x:Name="listView" ItemsSourceChangeCachingStrategy="ClearItems" />
listView.ItemsSourceChangeCachingStrategy = ItemsSourceChangeCachingStrategy.ClearItems;

NOTE

You can refer to our Xamarin ListView feature tour page for its groundbreaking feature representations. You can also explore our Xamarin.Forms ListView example to know how to render set of data items with Xamarin.Forms views or custom templates.

See Also

How to detect listview scrolling direction in Xamarin.Forms
How to maintain the same scroll position of ListView while updating ItemsSource at runtime
How to add a jump list with Xamarin.Forms ListView
How to load more items when scroll reached the end of list
How to automatically scroll to bring a selected item into the view
How to maintain the scroll position of ListView after clearing the filter at runtime
How to bring the item into view when adding at runtime in the listview
How to update the header height on scrolling in Xamarin.Forms ListView (SfListView)