Reputation: 39
When i am scrolling in CollectionView it starts to lag, probably loading of next pictures. What can i do with that? How can i optimize it?
Here is XAML:
<Grid BackgroundColor="#00aeef">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<CollectionView x:Name="myCollectionView" Grid.Row="0">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Frame Padding="0" BackgroundColor="#00d2ff" Margin="20" CornerRadius="30">
<StackLayout Padding="20">
<Label Text="{Binding Airline}" TextColor ="White" FontSize="30" HorizontalOptions="Center"/>
<Image Source="{Binding Url}" HeightRequest="200"/>
<Label Text="{Binding Plane, StringFormat='Plane: {0}'}" TextColor ="White" FontSize="15"/>
<Label Text="{Binding Airline, StringFormat='Airline: {0}'}" TextColor ="White" FontSize="15"/>
<Label Text="{Binding Livery, StringFormat='Livery: {0}'}" TextColor ="White" FontSize="15"/>
<Label Text="{Binding Registration, StringFormat='Reg: {0}'}" TextColor ="White" FontSize="15"/>
<Label Text="{Binding Airport, StringFormat='Airport: {0}'}" TextColor ="White" FontSize="15"/>
<Label Text="{Binding Date, StringFormat='Date: {0}'}" TextColor ="White" FontSize="15"/>
<Label Text="{Binding Comment, StringFormat='Comment: {0}'}" TextColor ="White" FontSize="15"/>
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Grid>
And here is my code:
public ShowPlanes()
{
InitializeComponent();
var db = new SQLiteConnection(_dbPath);
var data = db.Table<Airplane>().ToList();
myCollectionView.ItemsSource = data;
NavigationPage.SetHasNavigationBar(this, false);
}
Upvotes: 1
Views: 695
Reputation: 1
I check your code and I experiment it by different ways and finally, I am able why it is lagging. By adding scrollview and also remember to fix width of image also. Can you try this code:
<Grid BackgroundColor="#00aeef">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<scrollview>
<CollectionView x:Name="myCollectionView" Grid.Row="0">
<CollectionView.ItemTemplate>
<DataTemplate>
<StackLayout>
<Frame Padding="0" BackgroundColor="#00d2ff" Margin="20" CornerRadius="30">
<StackLayout Padding="20">
<Label Text="{Binding Airline}" TextColor ="White" FontSize="30" HorizontalOptions="Center"/>
<Image Source="{Binding Url}" HeightRequest="200" WidthRequest="200"/>
<Label Text="{Binding Plane, StringFormat='Plane: {0}'}" TextColor ="White" FontSize="15"/>
<Label Text="{Binding Airline, StringFormat='Airline: {0}'}" TextColor ="White" FontSize="15"/>
<Label Text="{Binding Livery, StringFormat='Livery: {0}'}" TextColor ="White" FontSize="15"/>
<Label Text="{Binding Registration, StringFormat='Reg: {0}'}" TextColor ="White" FontSize="15"/>
<Label Text="{Binding Airport, StringFormat='Airport: {0}'}" TextColor ="White" FontSize="15"/>
<Label Text="{Binding Date, StringFormat='Date: {0}'}" TextColor ="White" FontSize="15"/>
<Label Text="{Binding Comment, StringFormat='Comment: {0}'}" TextColor ="White" FontSize="15"/>
</StackLayout>
</Frame>
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</scrollview>
</Grid>
Upvotes: 0
Reputation: 39
This is working code for resizing:
var bitmap = SKBitmap.Decode(Path);
int h = bitmap.Height;
int w = bitmap.Width;
int newWidth = w;
int newHeight = h;
if (h > 1080 || w > 1080)
{
int rectHeight = 1080;
int rectWidth = 1080;
//aspect ratio calculation
float W = w;
float H = h;
float aspect = W / H;
await DisplayAlert("aspect", aspect.ToString() + w.ToString() + h.ToString(), "OK");
//new dimensions by aspect ratio
newWidth = (int)(rectWidth * aspect);
newHeight = (int)(newWidth / aspect);
await DisplayAlert("aspect", "h " + newHeight.ToString() + " w " + newWidth.ToString(), "OK");
//if one of the two dimensions exceed the box dimensions
if (newWidth > rectWidth || newHeight > rectHeight)
{
//depending on which of the two exceeds the box dimensions set it as the box dimension and calculate the other one based on the aspect ratio
if (newWidth > newHeight)
{
newWidth = rectWidth;
newHeight = (int)(newWidth / aspect);
}
else
{
newHeight = rectHeight;
newWidth = (int)(newHeight * aspect);
}
}
}
var resizedImage = bitmap.Resize(new SKImageInfo(newWidth, newHeight), SKBitmapResizeMethod.Lanczos3);
var image = resizedImage.Encode(SKEncodedImageFormat.Jpeg, 80);
var path = System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
var filepath = System.IO.Path.Combine(path, fileName);
string finalPath = filepath;
using (var stream = File.OpenWrite(filepath))
image.SaveTo(stream);
return finalPath;
}
Upvotes: 1
Reputation: 472
if your images are large try resizing it to your required size may be it will solve it below is very good reference.
https://learn.microsoft.com/en-us/samples/xamarin/xamarin-forms-samples/xamformsimageresize/
Upvotes: 1
Reputation: 697
If your images are quite big like over 100KB (each) then you may consider creating thumbnails to the same images with a different filename and smaller size like 10-20KB.
This will increase your app's speed.
To resize the image you can use the following code. The function will keep the aspect ratio of the original image. Also, the code will set to 72dpi the original image. The result will be a small optimized file ready for rendering to your view.
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
...
public static void CreatePreviewImage(string imageFullFilename, string previewFullFilename)
{
ImageCodecInfo jpgEncoder = GetEncoder(ImageFormat.Jpeg);
// Create an Encoder object based on the GUID
// for the Quality parameter category.
System.Drawing.Imaging.Encoder myEncoder = System.Drawing.Imaging.Encoder.Quality;
// Create an EncoderParameters object.
// An EncoderParameters object has an array of EncoderParameter
// objects. In this case, there is only one
// EncoderParameter object in the array.
EncoderParameters myEncoderParameters = new EncoderParameters(1);
EncoderParameter myEncoderParameter = new EncoderParameter(myEncoder, 75L); //default
myEncoderParameters.Param[0] = myEncoderParameter;
Bitmap originalimage = (Bitmap)System.Drawing.Image.FromFile(imageFullFilename, true);
originalimage.SetResolution(72, 72);
int w = originalimage.Width;
int h = originalimage.Height;
int pw = 0;
int ph = 0;
h = originalimage.Height * w / originalimage.Width;
if (w > h)
{
pw = 200;
ph = h * pw / w;
}
else
{
ph = 200;
pw = w * ph / h;
}
Bitmap previewImage = ImageHandlers.ResizeImage(originalimage, pw, ph);
previewImage.Save(previewFullFilename, jpgEncoder, myEncoderParameters);
}
public static Bitmap ResizeImage(Image image, int width, int height)
{
var h = image.Height;
var w = image.Width;
if (w > h)
{
height = h * width / w;
} else if( h < w )
{
width = w * height / h;
}
var destRect = new Rectangle(0, 0, width, height);
var destImage = new Bitmap(width, height);
destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
using (var graphics = Graphics.FromImage(destImage))
{
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
using (var wrapMode = new ImageAttributes())
{
wrapMode.SetWrapMode(WrapMode.TileFlipXY);
graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
}
}
return destImage;
}
public static ImageCodecInfo GetEncoder(ImageFormat format)
{
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageDecoders();
foreach (ImageCodecInfo codec in codecs)
{
if (codec.FormatID == format.Guid)
{
return codec;
}
}
return null;
}
Upvotes: 1