Articles in this section
Category / Section

How to load more items when scroll reached the end of ListView in Xamarin.Forms application?

2 mins read

SfListView provides support for load more items when reach end of the view. It can be achieved in sample level by finding whether the ListViewItems has reached at end or not by using Changed event of ScrollAxisBase in VisualContainer. By using Reflection, you can get the VisualContainer from SfListView and similarly get the ScrollAxisBase from VisualContainer.

 

Here, we have loaded an ActivityIndicator in FooterTemplate of SfListView, to indicate the items are being loaded in the background. By using Changed event, you can find whether reached the FooterItem based on LastBodyVisibleLineIndex property. If reached the FooterItem, you can load the items into the underlying collection. Please refer the below code snippet.

 

XAML

<syncfusion:SfListView x:Name="listView" ItemsSource="{Binding ContactsInfo}" ItemSize="60">
  <syncfusion:SfListView.FooterTemplate>
    <DataTemplate>
      <Grid>
        <ActivityIndicator x:Name="activityIndicator" Color="Blue" IsRunning="True"/>
      </Grid>
    </DataTemplate>
  </syncfusion:SfListView.FooterTemplate>
<syncfusion:SfListView.ItemTemplate>
  <DataTemplate>
    <ViewCell>
      <ViewCell.View>
        <Grid>
          <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="1" />
          </Grid.RowDefinitions>
          <Grid>
            <Grid.ColumnDefinitions>
              <ColumnDefinition Width="50" />
              <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
             <Image Source="{Binding ContactImage}" HeightRequest="50"/>
             <Grid Grid.Column="1">
               <Grid.RowDefinitions>
                 <RowDefinition Height="*" />
                 <RowDefinition Height="*" />
               </Grid.RowDefinitions>
               <Label Text="{Binding ContactName}"/>
               <Label Grid.Row="1" Grid.Column="0" Text="{Binding ContactNumber}" />
              </Grid>
            </Grid>
           <StackLayout Grid.Row="1" BackgroundColor="Gray" HeightRequest="1"/>
        </Grid>
       </ViewCell.View>
     </ViewCell>
   </DataTemplate>
 </syncfusion:SfListView.ItemTemplate>
</syncfusion:SfListView>

 

C#

public class ContactsViewModel: INotifyPropertyChanged
{
  bool isBusy = false;
  private int Id = 1;
 
  public ContactsViewModel ()
  {
    contactsinfo = new ObservableCollection<Contacts> ();
    LoadMoreData();
  }
 
  public async void LoadMoreData ()
  {
    isBusy = false;
 
    //To show ActivityIndicator if the items are loaded in the view. 
    if (contactsinfo.Count > 0)
      await Task.Delay(3000);
 
    //To ignore if items are being added till delayed time.
    if (isBusy)
      return;
 
    for (int i = 0; i < 20; i++)
    {
      Random r = new Random ();
      var contact = new Contacts ();
      contact.UserId = Id++;
      contact.ContactName = CustomerNames[i];
      contact.ContactNumber = 130+Id + " - " + 390+Id;
      contact.ContactImage = ImageSource.FromResource("SfListViewSample.Images.Image" + i + ".png");
      contactsinfo.Add(contact);
   }
    isBusy = true;
  }
}

 

C#

public partial class MainPage : ContentPage
{
  private ContactsViewModel viewModel;
  ScrollAxisBase scrollRows;
  public bool isFooterLoaded;
  VisualContainer visualContainer;
 
  public MainPage()
  {
  InitializeComponent();
   viewModel = new ContactsViewModel();
   this.BindingContext = viewModel;
   listView.FooterSize = 40;
  visualContainer = listView.GetType().GetRuntimeProperties().First(p => p.Name == "VisualContainer").GetValue(listView) as VisualContainer;
  scrollRows = visualContainer.GetType().GetRuntimeProperties().First(p => p.Name == "ScrollRows").GetValue(visualContainer) as ScrollAxisBase;
   scrollRows.Changed += ScrollRows_Changed;
  }
 
  private void ScrollRows_Changed(object sender, ScrollChangedEventArgs e)
  {
    var lastIndex = scrollRows.LastBodyVisibleLineIndex;
    var header = (listView.HeaderTemplate != null && !listView.IsStickyHeader) ? 1 : 0;
    var footer = (listView.FooterTemplate != null && !listView.IsStickyFooter) ? 1 : 0;
    var displayItemsCount = listView.DataSource.DisplayItems.Count;
    var totalItems = displayItemsCount + header + footer;
 
    //To stop loading when 60 items added to display items.
    if (displayItemsCount >=60)
    {
      listView.FooterSize = 0;
        return;
    }
 
      if (totalItems > 0 && lastIndex == (totalItems - 1))
      {
        if (!isFooterLoaded)
        {
          viewModel.LoadMoreData();
          isFooterLoaded = true;
        }
      }
      else
        {
          isFooterLoaded = false;
        }
     }
   }
}

 

The below screenshot show that load more items when reached end of the items in SfListView.

 

Screenshot:

C:\Users\muthukumaran.gnanavi\AppData\Local\Microsoft\Windows\INetCache\Content.Word\LoadMore.png

 

Click here to download the sample.


Conclusion

I hope you enjoyed learning about how to load more items when scroll reached the end of ListView in Xamarin.Forms application.

You can refer to our Xamarin.Forms ListView feature tour page to know about its other groundbreaking feature representations. You can also explore our Xamarin.Forms ListView documentation to understand how to create and manipulate data.

For current customers, you can check out our components from the License and Downloads page. If you are new to Syncfusion, you can try our 30-day free trial to check out our other controls.

If you have any queries or require clarifications, please let us know in the comments section below. You can also contact us through our support forumsDirect-Trac, or feedback portal. We are always happy to assist you!


Did you find this information helpful?
Yes
No
Help us improve this page
Please provide feedback or comments
Comments (0)
Please sign in to leave a comment
Access denied
Access denied