XAM280 Using ListView in Xamarin.Forms

Exercise 4: Add Pull to Refresh support (XAM280)

This exercise will continue modifying your FunFlacts application and simulate a pull-to-refresh action with our data. This feature is only supported on iOS and Android currently - you'll need to run it on one of those platforms to try it out.

To complete the exercise, you will need Visual Studio for Windows or macOS with the Xamarin development tools installed. You will also need either an emulator/simulator or a device to run the exercise on. Please see the setup page if you need help installing the Xamarin development environment.

Open the starter solution

This exercise is a continuation of the previous exercise. You can use your existing solution or begin from the prior Exercise 3 > Completed solution in your copy of the cloned or downloaded course materials.


Enable pull-to-refresh support

In order to support "pull-to-refresh", you need to set a property and subscribe to an event on the ListView.

  1. Open the AllFlags page and find the ListView definition.
  2. Set IsPullToRefreshEnabled to true.
  3. Add an event handler for the Refreshing event. This has a traditional EventHandler syntax (object sender, EventArgs e).
<ListView ItemsSource="{Binding Flags}"
    SelectedItem="{Binding CurrentFlag, Mode=TwoWay}"
    ItemTapped="OnItemTapped"
    IsPullToRefreshEnabled="True"
    Refreshing="OnRefreshing" />

Implement the refresh logic

Normally, in the refresh handler, you would initiate a background refresh of your data and, once it's complete, refresh the collection with new data. Since you only have local data to work with, you'll simulate this by reversing the order of our collection data.

  1. In the Refresh handler, reverse the items in the Flag collection. You can get access to it using the following statement:

    var collection = DependencyService.Get&lt;FunFlactsViewModel>().Flags;
    
  2. You can reverse the collection in-place, or use LINQ to create a new collection, clear the old one and replace all the items. Either approach is fine for a small number of items. If you have a lot of changes to make, it can be helpful to use a collection type that supports turning off notification such as the XamU OptimizedObservableCollection. The sample code below will do the reverse in-place by swapping the elements around.
  3. It might be helpful to put a delay into your method so the operation takes a second or two to finish. Use System.Threading.Tasks.Task.Delay with async and await to make sure you don't impact the UI thread. An example is in the below code.
  4. Set the IsRefreshing property on the ListView to false to indicate you are done refreshing the data. You can case the sender parameter to get to the ListView. Do this in a finally clause to make sure it gets executed.
  5. Run the application on either iOS or Android and "pull" the ListView down to activate the gesture. It should show an activity indicator and then reverse the list.
private async void OnRefreshing(object sender, EventArgs e)
{
    try
    {
        var collection = DependencyService.Get&lt;FunFlactsViewModel>().Flags;
        int i = collection.Count - 1, j = 0;
        while (i &gt; j)
        {
            var temp = collection[i];
            collection[i] = collection[j];
            collection[j] = temp;
            i--; j++;
            await System.Threading.Tasks.Task.Delay(200); // make it take some time.
        }
    }
    finally
    {
        // Turn off the refresh.
        ((ListView)sender).IsRefreshing = false;
    }
}

Exercise summary

In this exercise, you added support for the pull-to-refresh gesture.

You can view the completed solution in the Exercise 4 > Completed folder of your copy of the cloned or downloaded course materials.

Go Back