This is a migrated thread and some comments may be shown as answers.

Custom Cell with image stutters when scrolling on Android

8 Answers 221 Views
ListView
This is a migrated thread and some comments may be shown as answers.
Christopher
Top achievements
Rank 2
Christopher asked on 17 Sep 2015, 10:28 AM

Hi Team,

 I have a RadListView in Xamarin Forms which has a custom cell. This cell contains a number of objects plus an Image. If I deploy this to an Android device is stutters when scrolling the list. If I remove the Image then the list scroll is smooth. How can I get a smooth scrolling list with an image attached? I am using the "UI for Xamarin Q2 2015" dlls.

8 Answers, 1 is accepted

Sort by
0
Tsvyatko
Telerik team
answered on 23 Sep 2015, 02:53 PM
Hello Christopher,

Thank you for contacting us! The described behavior is known limitation in Android image visualization.

Currently, images are loaded in the UI thread and thus blocking the measure cycle. We are working on resolving this by building component that will handle this directly in the native platform in one of our future releases.



Regards,
Tsvyatko
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Christopher
Top achievements
Rank 2
answered on 24 Sep 2015, 07:22 AM

Hi Tsvyatko,

Do you know when this future release will be available?

Thanks.

0
Tsvyatko
Telerik team
answered on 28 Sep 2015, 01:44 PM
Hi Christopher,

The fix for this issue will be released in a build in a beginning of November.

Please excuse us for the inconvenience caused!


Regards,
Tsvyatko
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
MSiccDev
Top achievements
Rank 2
answered on 11 Sep 2016, 03:45 PM
I am experiencing the same problem in a recent project. Using Xamarin Forms ListView, the problem does not appear. Any idea on how to solve this (as it must be something on the setup if the update to RadListView went already out last Nov...)
0
Tsvyatko
Telerik team
answered on 12 Sep 2016, 03:08 PM
Hello Christopher,

Thank you for getting back to us.

Since, the last November we have some major improvements in the rendering of the listview. In the cases where item template contains images you can  boost the list view performance by adding our ImageRenderer the the set of rednderers:

[assembly: Xamarin.Forms.ExportRenderer(typeof(Image), typeof(Telerik.XamarinForms.Common.Android.AndroidImageRenderer))]

Let us know if this helps. If not would it be possible to share some additional information regarding the setup of the listview - template complexity,variable item size, container that listview is nested in.

Regards,
Tsvyatko
Telerik by Progress
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
MSiccDev
Top achievements
Rank 2
answered on 12 Sep 2016, 06:02 PM

Hi,

I am not the initiator of this thread, I just thought it makes sense to add my problem here. Feel free to move this to a new thread if it suits better for your internals.

I am using a pretty complex ViewCell template (well, at least it is in the Xamarin Forms world). Here is the code I am using:

01.<telerikDataControls:RadListView x:Name="NewsListView" Grid.Row="1" ItemsSource="{Binding NewsTabVm.NewsPosts}" SelectionMode="None" SelectionGesture="Tap"  >
02.  <telerikDataControls:RadListView.LayoutDefinition>
03.    <listView:ListViewLinearLayout VerticalItemSpacing="6" HorizontalItemSpacing="6"></listView:ListViewLinearLayout>
04.  </telerikDataControls:RadListView.LayoutDefinition>
05. 
06.  <telerikDataControls:RadListView.Behaviors>
07.    <behaviors:EventToCommandBehavior EventName="ItemTapped" Command="{Binding NewsTabVm.PostSelectedCommand}" Converter="{StaticResource ItemTappedConverter}"></behaviors:EventToCommandBehavior>
08.  </telerikDataControls:RadListView.Behaviors>
09. 
10.  <telerikDataControls:RadListView.ItemTemplate>
11.    <DataTemplate>
12.      <listView:ListViewTemplateCell>
13.        <listView:ListViewTemplateCell.View>
14.          <Grid HeightRequest="200" Margin="6" BackgroundColor="Black">
15.            <Grid>
16.              <Grid.RowDefinitions>
17.                <RowDefinition Height="*"></RowDefinition>
18.              </Grid.RowDefinitions>
19.              <Grid.ColumnDefinitions>
20.                <ColumnDefinition Width="*"></ColumnDefinition>
21.              </Grid.ColumnDefinitions>
22.              <ffImgLoading:CachedImage Grid.Row="0" Grid.Column="0"
23.                                        HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"
24.                                        CacheDuration="5" Source="{Binding Image}" MinimumHeightRequest="200"
25.                                        Aspect="AspectFill" FadeAnimationEnabled="True">
26.              </ffImgLoading:CachedImage>
27.            </Grid>
28. 
29.            <Grid VerticalOptions="Start" HorizontalOptions="EndAndExpand" BackgroundColor="Lime" IsVisible="{Binding IsLeitArtikel}" WidthRequest="28" HeightRequest="28">
30.              <Image Source="ic_star_white_24dp.png" HorizontalOptions="Center" VerticalOptions="Center"></Image>
31.            </Grid>
32. 
33.            <Grid VerticalOptions="EndAndExpand" BackgroundColor="#96000000" Margin="0,0,0,-2">
34.              <Grid.RowDefinitions>
35.                <RowDefinition Height="Auto"></RowDefinition>
36.                <RowDefinition Height="Auto"></RowDefinition>
37.              </Grid.RowDefinitions>
38.              <Label Grid.Row="0" Text="{Binding Title}" FontAttributes="Bold" FontSize="Medium" Margin="6,0" TextColor="White"></Label>
39.               
40.              <Grid Grid.Row="1" Margin="6,0">
41.                <Grid.ColumnDefinitions>
42.                  <ColumnDefinition Width="*"></ColumnDefinition>
43.                  <ColumnDefinition Width="*"></ColumnDefinition>
44.                </Grid.ColumnDefinitions>
45.                <StackLayout Orientation="Horizontal" Grid.Row="0" VerticalOptions="Center" Margin="0,0,0,6">
46.                  <Label Text="{Binding Date}" VerticalOptions="Center"></Label>
47.                  <Label  Text="{Binding AuthorName}" VerticalOptions="Center"></Label>
48.                </StackLayout>
49.                <StackLayout Orientation="Horizontal" Grid.Column="1" HorizontalOptions="EndAndExpand" Margin="0,0,0,6">
50.                  <Label Text="{Binding CommentCount}" VerticalOptions="Center"></Label>
51.                  <Image Source="ic_mode_comment_white_24dp.png" WidthRequest="18" HeightRequest="18" ></Image>
52.                </StackLayout>
53.              </Grid>
54.            </Grid>
55.          </Grid>
56.        </listView:ListViewTemplateCell.View>
57.      </listView:ListViewTemplateCell>
58.    </DataTemplate>
59.  </telerikDataControls:RadListView.ItemTemplate>
60. 
61. 
62.</telerikDataControls:RadListView>

I have used this kind of template already a thousand times on Windows (Phone 7/8.x/10) without any problems.

Adding you ImageRenderer has no recognizable imapct, but that might be due to the fact I am using the FFImageLoading library because of its advanced techniques of caching.

Once I have scrolled down the whole list, it is working a little better during scrolling. The ListView is inside a Grid with two rows, the first one is defined as Star and the second is defined as Auto. The Grid is inside a ContentPage that is part of a two page CarouselPage. Data is bound via MVVM.

I am open for any suggestions.

 

0
Tsvyatko
Telerik team
answered on 15 Sep 2016, 11:19 AM
Hi Marco,

Thank you for sharing this information. It will help us better identify performance issues in real case scenarios and add improvements in the future releases.

Regarding the image renderer - indeed it will not bring any change as it basically apply performance improvements only to the rendering of the default Xamarin Image control in Android.

What I can suggest that will work good both in the ours and the default listview is creating custom cell that derive from templatecell/viewcell and apply the data in code-behind directly the elements in the View (without using binding or reflection) e.g.:

  var product= BindingContext as Product;
 
        if (product!= null) {
            TextLabel.Text = product.Name;
            DescriptionLabel.Text = product.Description;
...
        }

We are planing to issue a blogpost how to apply this aproach using our listviewtemplate cell.

Regards,
Tsvyatko
Telerik by Progress
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Lance | Manager Technical Support
Telerik team
answered on 15 Sep 2016, 08:27 PM
Hello Marco,

I wanted to follow-up quickly with an example using Tsvyatko's recommended approach, but using FFImageLoading in the template. Find it attached (you didn't specify which platform so I included all but tested extensively on Android).

Ultimately, after applying the custom TemplateCell, I was unable to determine a specific link between the RadListView and FFImage's CachedImage component leading to the performance problem as the images loaded pretty quick despite being high res (demo used Bing Images's 1080 images).

I did some further optimization and got significant improvement in load times by doing these:

- Set the DownsampleWidth to match what the container's width is (significant boost from this)
- Try using a different CacheType (it has both Disk and Memory), I chose Memory for the purposes of the demo. If your app will be showing the same images on multiple app launches, Disk or All is better 

Here's a page from the FFImage.CacheImage docs, it has some great examples you could apply (in the custom TemplateCell or in the XAML).

Once the image is downloaded and cached by the control, it loads quickly when scrolling through the item containers. For quick reference, here is the XAML and CustomTemplateCell code.

XAML
<telerikDataControls:RadListView ItemsSource="{Binding BingImages}" >
    <telerikDataControls:RadListView.ItemTemplate>
      <DataTemplate>
        <layouts:FastTemplateCell>
          <layouts:FastTemplateCell.View>
            <Grid>
              <Grid.RowDefinitions>
                <RowDefinition/>
                <RowDefinition Height="Auto"/>
              </Grid.RowDefinitions>
              <forms:CachedImage x:Name="image" Grid.Row="0"
                                 HorizontalOptions="FillAndExpand"
                                 VerticalOptions="FillAndExpand"
                                 CacheDuration="5"
                                 CacheType="All"
                                 DownsampleWidth="300"
                                 HeightRequest="200"
                                 Aspect="AspectFill"
                                 FadeAnimationEnabled="True"/>
              <Grid Grid.Row="1" BackgroundColor="White">
                <StackLayout Padding="16">
                  <Label x:Name="title" TextColor="#362F2D" FontAttributes="Italic" FontSize="16" LineBreakMode="TailTruncation"/>
                  <Label x:Name="author" TextColor="#534741" FontSize="12" LineBreakMode="TailTruncation" />
                </StackLayout>
              </Grid>
            </Grid>
          </layouts:FastTemplateCell.View>
        </layouts:FastTemplateCell>
      </DataTemplate>
    </telerikDataControls:RadListView.ItemTemplate>
  </telerikDataControls:RadListView>


C#
public class FastTemplateCell : ListViewTemplateCell
    {
        private FFImageLoading.Forms.CachedImage image;
 
        private Label titleLabel;
 
        private Label authorLabel;
 
        protected override void OnBindingContextChanged()
        {
            base.OnBindingContextChanged();
 
            this.EnsureCachedElements();
 
            var data = this.BindingContext as BingImage;
 
            if (data != null)
            {
                this.image.Source = $"http://www.bing.com{data?.url}";
 
                this.authorLabel.Text = data?.copyright;
                this.titleLabel.Text = data?.startdate;
            }
        }
 
        private void EnsureCachedElements()
        {
            if (this.image == null)
            {
                this.image = this.View.FindByName<CachedImage>("image");
            }
 
            if (titleLabel == null)
            {
                this.titleLabel = this.View.FindByName<Label>("title");
            }
 
            if (authorLabel == null)
            {
                this.authorLabel = this.View.FindByName<Label>("author");
            }
        }
    }

Please let us know if this doesn't resolve the issue and we'll investigate further. If possible, update the demo project to replicate the problem you're seeing.

Thank you for contacting Support and for choosing Telerik!

Regards,
Lance | Tech Support Engineer, Sr.
Telerik by Progress
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Tags
ListView
Asked by
Christopher
Top achievements
Rank 2
Answers by
Tsvyatko
Telerik team
Christopher
Top achievements
Rank 2
MSiccDev
Top achievements
Rank 2
Lance | Manager Technical Support
Telerik team
Share this question
or