Xamarin Forms ListView Programatic Refresh Not Stopping on Android When Page Loaded

xamarin forms force page reload
xamarin forms pull to refresh contentpage
reload page in xamarin forms
refresh ui xamarin forms
xaml listview refresh

I have Portable project in Visual Studio 2015 with a ListView that gets populated with some data via an API call through the following function refreshData:

async Task refreshData()
{
    myListView.BeginRefresh();
    var apiCallResult = await App.Api.myApiGetCall();            
    myListView.ItemsSource = apiCallResult;
    myListView.EndRefresh();    
}

refreshData() is called in

protected override void OnAppearing()
{
    base.OnAppearing();
    refreshData();
}

Everything is working fine except on Android where the refresh indicator is not stopping or disappearing on EndRefresh() when the page is initially loaded. The page is in a TabbedPage so I can go to a different tab and then return to this page and the refresh indicator properly starts and stops with completion of my API call.

Why is refresh is not stopping when the page initially loads on Android? Any help would be appreciated.

Note: This works perfectly fine when I run on iOS.

So far I've tried:

  1. replacing myListView.BeginRefresh() with myListView.IsRefreshing = true and myListView.EndRefresh() with myListView.IsRefreshing = false

  2. Using Device.BeginInvokeOnMainThread(() => {//update list and endRefresh}).

  3. Using async void refreshData() instead of async Task refreshData().

Try this:

async void refreshData()
{
    Device.BeginInvokeOnMainThread(() => {
        myListView.BeginRefresh();
        var apiCallResult = await App.Api.myApiGetCall();
        myListView.ItemsSource = apiCallResult;
        myListView.EndRefresh();
    });
}

Apparently, there is no need for "Task" anymore.

If the error occurs only in Android, it's possible that it's just the way Android handles threads. It does not allow threads to change visual elements directly. Sometimes when we try to do that it throws a silent exception and the code action have no practical effect.

Pull down refresh indicator not stopping after complete loading , Here is my sample xaml <ListView ItemsSource="{Binding EmployeeList}" Pull down refresh indicator not stopping after complete loading. Harshita INMember. January 2018 edited January 2018 in Xamarin.Forms. Here is my sample  The Xamarin Forms ListView control has the ability to allow the user to pull down from the top of the ListView to trigger a refresh command. I say a refresh command, because the pull to refresh, just triggers a command and you can do whatever you want in that command, including not updating the ListView.

Personally I can get this problem when I start ListView refreshing in the Page Contructor and stop it after the data is loaded. Sometimes (quite often) Xamarin.Forms ListView doesn't cancel refreshing animation.

I believe you faced with a quite common issue with Android SwipeRefreshLayout: it may not stop refreshing animation after setRefreshing(false) called. Native Android developers use the following approach:

swipeRefreshLayout.post(new Runnable() {
    @Override
        public void run() {
            mSwipeRefreshLayout.setRefreshing(refreshing);
    }
});

Interestingly, Xamarin.Forms uses this approach when it sets initial refreshing status (code); however, it is not enough. You need a custom renderer:

public class ExtendedListViewRenderer : ListViewRenderer
{
    /// <summary>
    /// The refresh layout that wraps the native ListView.
    /// </summary>
    private SwipeRefreshLayout _refreshLayout;

    public ExtendedListViewRenderer(Android.Content.Context context) : base(context)
    {
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            _refreshLayout = null;
        }
        base.Dispose(disposing);
    }

    protected override void OnElementChanged(ElementChangedEventArgs<ListView> e)
    {
        base.OnElementChanged(e);
        _refreshLayout = (SwipeRefreshLayout)Control.Parent;
    }

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == ListView.IsRefreshingProperty.PropertyName)
        {
            // Do not call base method: we are handling it manually
            UpdateIsRefreshing();
            return;
        }
        base.OnElementPropertyChanged(sender, e);
    }

    /// <summary>
    /// Updates SwipeRefreshLayout animation status depending on the IsRefreshing Element 
    /// property.
    /// </summary>
    protected void UpdateIsRefreshing()
    {
        // I'm afraid this method can be called after the ListViewRenderer is disposed
        // So let's create a new reference to the SwipeRefreshLayout instance
        SwipeRefreshLayout refreshLayoutInstance = _refreshLayout;

        if (refreshLayoutInstance == null)
        {
            return;
        }

        bool isRefreshing = Element.IsRefreshing;
        refreshLayoutInstance.Post(() =>
        {
            refreshLayoutInstance.Refreshing = isRefreshing;
        });
    }
}

Customization in Xamarin Pull To Refresh control, Learn about Customization support in Syncfusion Xamarin Pull To Refresh RefreshContentHeight; Programmatic Support; Host SfDataGrid as pullable content SfPullToRefresh controls provides support for loading any custom control as This is how the final output will look like on iOS, Android and Windows Phone  Learn how to refresh a ListView in Xamarin Forms to add or remove items from a list. The interactive transcript could not be loaded. Xamarin Forms ListView SelectedItem in MVVM

Xamarin.Forms RefreshView, Forms RefreshView is a container control that provides pull to refresh a scrollable control, such as ScrollView , CollectionView , or ListView . Screenshot of a RefreshView refreshing data, on iOS and Android Disable a RefreshView. An application may enter a state where pull to refresh is not a valid​  Scrolling in Xamarin ListView (SfListView) 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.

Pull-to-refresh with Xamarin.Forms RefreshView - DevBlogs, One frequently-asked question with CollectionView, or other scrolling layouts, is how to add Pull-to-Refresh functionality similar to ListView. The  Hello: started today to use the listview of syncfusion, but I encountered a problem and my listview is a list of computers which are connected and disconnected to a server and in the list it marks those that are connected and disconnected, is changing every little time, the problem well in that the list is left to me as it is loaded when I start the app, with the normal listview if it is

Xamarin.Forms - ListView With Pull To Refresh, Xaml page. You now have a basic Xamarin.Forms app. Click the Play button to try it out. Setting  Pull To Refresh Tutorial using Xamarin.Forms This is a quick tutorial of how to implement Pull To Refresh Command on your Xamarin.Forms ListViews. Sample Cod

Adding Swipe-to-Refresh To Your App, The swipe-to-refresh user interface pattern is implemented entirely within the parent of a ListView or GridView , and implementing the refresh behavior that bar to ensure that users who may not be able to perform a swipe gesture can Content and code samples on this page are subject to the licenses  - fixes #2663 * [Shell] fix queryParam navigation (#4843) when navigating to pages, not shell-section, handle the queryParams - fixes #4837 * Make ListView CachingStrategy property visible to Intellisense (#4846) * Implement Android single selection in CollectionView (#4651) * Implement Android single selection * Fix naming conflicts with

Comments
  • try to use Device.BeginInvokeOnMainThread (//your code related update list view);
  • just tried, didn't work.
  • try to use only myListView.EndRefresh(); ..remove myListView.Isreferhing=false
  • I've tried that as well. Doesn't make a difference.
  • Did you find a solution
  • > Aparantly you don't need of the "Task" return too. Well, you probably need it, otherwise you would execute network call in the UI thread
  • You're right @NikolaiDoronin. It make sense. So the whole approach in my answer is wrong. It's not the best way to do that
  • Why has this answer received a down vote? This is how it should be done, even though the code shared uses an additional framework. But the idea is to make a one way binding for the IsRefreshing property, and make it implement INotifyPropertyChanged, and set it to false after your code that updates your list.
  • @Elisabeth that's true, but I can confirm that this can lead to an endless refreshing indicator in a tabbed page. I have it inside a Task.Run(async () => await //.. and changing the "IsRefreshing" bool property of the VM thats bound to the ListView will sometimes not propergate the change event to the View. What Ingenator described is as he said just a "MVVM pattern". Nothing more.
  • @Csharpest Beware when updating in a task. If you have run off the main thread or didn’t complete the work, it is when your property change will never propagate to the view. Use ‘Device.BeginInvokeOnMainThread’ to update.