MainakChoudhury
MainakChoudhury

Reputation: 524

Image disappearing on scrolling in listview xamarin forms

ListView Xamarin forms

I have ListView in xamarin forms. On scrolling this Listview up and down this clock image appears and disappears inconsistently.

Even if i hardcode the visibility, the image is inconsistent.

<DataTemplate x:Key="itemTemplate">
            <ViewCell>
                <StackLayout Orientation="Horizontal" Spacing="5" Padding="0,0,10,0">
                    <Label HorizontalOptions="StartAndExpand"  VerticalOptions="Center" TextColor="#455560" Text="{Binding DispenseTypeWithMachineCount}" WidthRequest="250"/>
                    <Image IsVisible="{Binding IsServiceInProgress}" Source="ic_progress.png" HeightRequest="24" WidthRequest="24" VerticalOptions="Center" HorizontalOptions="EndAndExpand"/>
                </StackLayout>
            </ViewCell>
        </DataTemplate>

<ListView x:Name="ListViewAccounts" Margin="0,0,0,0" ItemsSource="{Binding ExpandedGroups}" GroupDisplayBinding="{Binding Title}" IsGroupingEnabled="true" ItemTemplate="{StaticResource accountTemplateSelector}" GroupHeaderTemplate="{StaticResource groupHeaderTemplate}">
            <ListView.Behaviors>
                <behaviors:EventToCommandBehavior EventName="ItemTapped" Command="{Binding Path=BindingContext.ListViewAccountItemTappedCommand                               Source={x:Reference ListViewAccounts}}" />
            </ListView.Behaviors>
            <x:Arguments>
                <ListViewCachingStrategy>RecycleElement</ListViewCachingStrategy>
            </x:Argume

Upvotes: 2

Views: 1807

Answers (2)

Mateus Wolkmer
Mateus Wolkmer

Reputation: 735

I've also had previous problems with moving images, their behaviour is inconsistent. I've solved most of them by using vectorized icons wherever possible, instead of image files, and that seems to be suitable for your case as you're also using an icon.

I recomend using FFImageLoading (as recommended before) to load SVGs, it loads fast and caches them for future use. Do the following to replace your PNG reference to a SVG:

  1. Install FFImageLoading and FFImageLoading.Svg into your project from the NuGet packages manager
  2. Download clock.svg from FontAwesome
  3. Place the icon inside a folder in your project and set its Build Action to Embedded resource
  4. Add the FFImageLoading reference to the top of your XAML:
    xmlns:ffsvg="clr-namespace:FFImageLoading.Svg.Forms;assembly=FFImageLoading.Svg.Forms"
  1. Replace your Image element inside the DataTemplate with the following:
    <ffsvg:SvgCachedImage IsVisible="{Binding IsServiceInProgress}" Source="resource://[PATH_TO_YOUR_SVG_INSIDE_NAMESPACE].clock.svg" HeightRequest="24" WidthRequest="24" VerticalOptions="Center" HorizontalOptions="EndAndExpand"/>

Example:

    <ffsvg:SvgCachedImage IsVisible="{Binding IsServiceInProgress}" Source="resource://MyProject.Resources.clock.svg" HeightRequest="24" WidthRequest="24" VerticalOptions="Center" HorizontalOptions="EndAndExpand"/>

SVGs are lighter to load, have a better resolution, and the flicker should be solved.

Another thing that could help is messing around with the List CachingStrategy property, as it defines the way elements in the List are cached and rendered. Check this for more info about ListView Performance.

Upvotes: 2

LeRoy
LeRoy

Reputation: 4436

You can also change how list views recycle elements, I noticed you are implementing it but yours looks weird:

Types of strategies :

  • RetainElement // the default value

  • RecycleElement

  • RecycleElementAndDataTemplate

ListView:

<ListView
    x:Name="ListViewAccounts"
    Margin="0,0,0,0"
    ItemsSource="{Binding ExpandedGroups}"
    GroupDisplayBinding="{Binding Title}"
    IsGroupingEnabled="true"
    ItemTemplate="{StaticResource accountTemplateSelector}"
    CachingStrategy="RecycleElement"
    GroupHeaderTemplate="{StaticResource groupHeaderTemplate}">
    <ListView.Behaviors>
        <behaviors:EventToCommandBehavior
            EventName="ItemTapped"
            Command="{Binding Path=BindingContext.ListViewAccountItemTappedCommand,  Source={x:Reference ListViewAccounts}}" />
    </ListView.Behaviors>
</ListView>

Upvotes: 2

Related Questions