innom
innom

Reputation: 1125

Xamarin.forms DataReload Function: When called from eventhandler, observablecollection flickers immensly

I reload items from a simple function.

If I call the reload function statically, like this:

   LoadMoreAds(4);
   LoadMoreAds(8);
   LoadMoreAds(12);
   LoadMoreAds(16);

everything works fine.

But If I put this inside the event handler for item appearing to make it dynamically reload:

private void listview_allAds_FlowItemAppearing(object sender, ItemVisibilityEventArgs e)
{
    TinyAd current = e.Item as TinyAd;
            
    if (current == contentOfListView[contentOfListView.Count-1])
    {
        LoadMoreAds();
    }
}

The items that are already inside the observable collection flicker badly for a few frames until the reload is done. then they are fine until the next reload happens.

This is my list:

  <flv:FlowListView
                    Grid.Row="1"
                    BackgroundColor="Transparent"
                    Scrolled="listview_allAds_Scrolled"
                    VerticalOptions="Fill"
                    FlowItemAppearing="listview_allAds_FlowItemAppearing"                 
                    Refreshing="listview_allAds_Refreshing"
                    FlowColumnCount="1"
                    IsPullToRefreshEnabled="True"
                    Margin="5,0,5,0"
                    VerticalScrollBarVisibility="Never"
                    HasUnevenRows="True"
                    x:Name="listview_allAds" />

Has anyone experienced a similar issue?

Upvotes: 0

Views: 53

Answers (1)

ToolmakerSteve
ToolmakerSteve

Reputation: 21341

You can probably improve (but not eliminate) the flickering by changing the timing of how you add the new items. The concept is to do as much work as possible before adding to the observable collection.

In pseudo-code:

var newItems = new List<MyItem>();
... logic that fetches new ads, sets their properties, and adds elements to newItems ...
...
// Now all the data is ready; add to the collection.
foreach (var item in newItems)
    contentOfListView.Add(item);

Why this might help: the flickering likely means the list is being refreshed repeatedly, possibly multiple times per new item (depending on exactly what your code does). The goal of the above code is to tell xaml about those adds "all at once" (or close to that). With luck, it will only do one or two refreshes of the view.


If fetching ads (and any resources they need, such as images), takes a significantly long time, it is best to do that work in the background. To avoid freezing the UI.

Task.Run( () =>
{
    // We are now on a background thread.
    var newItems = new List<MyItem>();
    ... logic that fetches new ads, sets their properties, and adds elements to newItems ...
    
    // Now all the data is ready; add to the collection.
    Device.BeginInvokeOnMainThread( () =>
    {
        // We are now on MainThread.
        foreach (var item in newItems)
            contentOfListView.Add(item);
    }
}

Upvotes: 1

Related Questions