Xamarin: First call to InitializeComponent slow - xamarin

The problem is that the first call to a page's InitializeComponent is very slow. Thus the page transition animation is laggy for the first time. StackLayout with a few Labels and a Grid can take like 70 ms on my phone. I removed almost everything from the page and tried to find a bottle neck but it seems that even an empty grid adds a significant amount of time. So my full page takes something like 180 ms and when it's loaded for the first time there is almost no animation and it looks like a freezing app. Consecutive animations take like 15~20 ms.
Answering your potential questions: Yes, I have XAML compilation enabled. And yes, I've tried Release build but it doesn't help much.
Updated
I have added a button and a static grid to an items detail of default Xamarin application created in Visual Studio.
This is current content of the page:
<StackLayout Spacing="20" Padding="15">
<Label Text="Text:" FontSize="Medium" />
<Label Text="{Binding Text}" FontSize="Small"/>
<Label Text="Description:" FontSize="Medium" />
<Label Text="{Binding Description}" FontSize="Small"/>
<Button Text="{Binding Text}" />
<Grid RowSpacing="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Text="Coins:" FontAttributes="Bold" />
<Label Grid.Row="0" Grid.Column="1" Text="111" HorizontalTextAlignment="End" />
<Label Grid.Row="0" Grid.Column="2" Text="Total coins:" FontAttributes="Bold" />
<Label Grid.Row="0" Grid.Column="3" Text="100000" HorizontalTextAlignment="End"/>
<Label Grid.Row="1" Grid.Column="0" Text="Gold:" FontAttributes="Bold" />
<Label Grid.Row="1" Grid.Column="1" Text="222" HorizontalTextAlignment="End" />
<Label Grid.Row="1" Grid.Column="2" Text="Table gold:" FontAttributes="Bold" />
<Label Grid.Row="1" Grid.Column="3" Text="120 " HorizontalTextAlignment="End"/>
</Grid>
</StackLayout>
And this is how I measure the time:
public partial class ItemDetailPage : ContentPage
{
public ItemDetailPage()
{
var start = DateTime.Now.ToUniversalTime().Millisecond;
InitializeComponent();
var end = DateTime.Now.ToUniversalTime().Millisecond;
Debug.WriteLine($"ItemDetailPage.InitializeComponent: {end - start}");
BindingContext = new ItemDetailViewModel();
}
}

Related

CollectionView Xamarin grid view sizing

I am working with a collectionview using GridItemsLayout orientation=“Vertical” Span=“2”.
When I click on a button that expands the lower part of my grid item. Currently only by using ItemSizingStrategy.MeasureAllItems I am able to get the lower part to expand. I was wondering if there is a way of controlling the item positioning on the image so the images always align and only the lower half expands evenly.
I am aware each item has its own layout, but this looks messy. I’ve read the documentation mention this type of sizing.
<ContentPage.Content>
<StackLayout>
<CollectionView x:Name="CollectionList"
VerticalOptions="FillAndExpand"
ItemsSource="{Binding Shares}"
IsGrouped="True"
ItemSizingStrategy="MeasureAllItems">
<!--HEADER-->
<CollectionView.GroupHeaderTemplate>
<DataTemplate>
<StackLayout Orientation="Horizontal"
Padding="5"
BackgroundColor="#f7f7fb">
<Label x:Name="labelname"
Text="{Binding GroupKey}"
/>
<Button Text=" More"
FontSize="16"
Clicked="OpenButton_Clicked"/>
</StackLayout>
</DataTemplate>
</CollectionView.GroupHeaderTemplate>
<!--TEMPLATING-->
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical" Span="2" />
</CollectionView.ItemsLayout>
<!--BODY-->
<CollectionView.ItemTemplate>
<DataTemplate x:DataType="viewmodels:ShareViewModel">
<Grid Padding="5" Margin="1,0,1,0" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="50" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ImageButton x:Name="image"
Source="{Binding ImageLink}"
WidthRequest="150"
Clicked="FullImageView"
Grid.ColumnSpan="2"
Aspect="AspectFill"
Grid.Row="0"
Grid.Column="0"/>
<Label FontSize="16"
Text="{Binding Name}"
Grid.Row="1"
Grid.Column="0"/>
<Label x:Name="label_more"
Text="More"
Grid.Row="1"
Grid.Column="1"
HorizontalTextAlignment="End"/>
<Label
Text="{Binding CreateDate}"
Grid.Row="2"
Grid.Column="0"/>
<ImageButton IsVisible="{Binding TVNImageSet}"
Command="{Binding BindingContext.ToggleTVNCommand, Source={x:Reference Name=sharepage}}"
CommandParameter="{Binding .}"
Source="addresscard.png"
Grid.Row="2"
Grid.Column="1">
</ImageButton>
<!--Lower Section if the card is tapped (EXPAND)-->
<StackLayout
IsVisible="{Binding TVNVisible}"
Grid.Row="3"
Grid.ColumnSpan="2">
<StackLayout Orientation="Horizontal"
IsVisible="{Binding PhoneVisible}"
ClassId="{Binding Phone}">
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"
NumberOfTapsRequired="1"
/>
</StackLayout.GestureRecognizers>
<Image Source="call.png"
WidthRequest="15"/>
<Label
FontSize="12"
Text="{Binding Phone}" />
</StackLayout>
<Label
FontSize="12"
Text="{Binding Address}"
IsVisible="{Binding AddressVisible}">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped_1" NumberOfTapsRequired="1"/>
</Label.GestureRecognizers>
</Label>
</StackLayout>
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
All BindingContext.ToggleTVNCommand does is set TVNVisible to true which shows the lower half the "expanding potion". I don't need to use collection view if there is an easier way fo displaying this data, but CollectionVView seemed like the best choice for the layout and item source I wanted.
After digging around GitHub forums on bugs and updates for Xamarin, someone mentioned to just work with SyncFusion's sfListview the membership is not that bad and my company is willing to pay for it if it makes working with Xamarin easier.
That wasn't the solution I was hoping for, but it works and their customer support is great.
below is the reference
https://help.syncfusion.com/xamarin/listview/working-with-sflistview

Spawn Images on certain position Xamarin Forms

Hello Xamarin community!
I just started with Xamarin Forms and wanted to create a simple app, which helps counting on a card game.
The points should be visualized in this image and should look like the following one:
In the first row there should be a horizontal line every fifth line and on the second line there should be a horizontal line every second line.
Here is how it looks like when i manually add the lines and add a backgroundcolor for visualization:
Here is the View:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="2*" />
<RowDefinition Height="*" />
<RowDefinition Height="8*" />
<RowDefinition Height="8*" />
<RowDefinition Height="8*" />
<RowDefinition Height="*" />
<RowDefinition Height="4*" />
<RowDefinition Height="4*" />
</Grid.RowDefinitions>
<Entry Text="{Binding Team1.Name}" Grid.Column="0" Grid.Row="0" />
<Label Text="150" Grid.Column="0" Grid.Row="1" />
<Entry Text="{Binding Team2.Name}" Grid.Column="1" Grid.Row="0" />
<Label Text="129" Grid.Column="1" Grid.Row="1" />
<Image Source="Schlange.png"
Aspect="Fill"
BackgroundColor="#"
Grid.ColumnSpan="2"
Grid.Row="2"
Grid.RowSpan="3" />
<Image Scale="0.5" BackgroundColor="Gray" Source="Strich1.png" Grid.Column="0" Grid.Row="2" Margin="0,0,0,0"/>
<Image BackgroundColor="Blue" Source="Strich1.png"/>
<Button BackgroundColor="Transparent" Grid.Column="0" Grid.Row="2" />
<Button BackgroundColor="Transparent" Grid.Column="0" Grid.Row="3" />
<Button BackgroundColor="Transparent" Grid.Column="0" Grid.Row="4" />
<Button BackgroundColor="Transparent" Grid.Column="1" Grid.Row="2" />
<Button BackgroundColor="Transparent" Grid.Column="1" Grid.Row="3" />
<Button BackgroundColor="Transparent" Grid.Column="1" Grid.Row="4" />
<Label Text="1" Grid.Column="0" Grid.Row="5"></Label>
<Label Text="-1" Grid.Column="1" Grid.Row="5"></Label>
<Entry Grid.Column="0" Grid.Row="6"></Entry>
<Entry Grid.Column="1" Grid.Row="6"></Entry>
<Button Text="Runde!" Grid.Row="7" Grid.ColumnSpan="2" />
</Grid>
My Question would be how to spawn Images on certain positions? Is this even possible with a grid? What happens to mobile phones with different resolution?
Thanks in advance and don't hesitate to ask if needed.

Xamarin 3 StackLayouts

I am making a page where there is a top title, an image in the middle and some text under it and then two buttons at the bottom for yes or no. As you can see the buttons are getting pushed down too much and getting cut off. I can't figure out how to move the text up a little or reduce the spacing between the image and the title and text. I know I probably could do this with absolute layouts but I am not sure how it would work with larger/smaller screens.
Here is my XAML for the image.
<ContentPage BackgroundColor="#FF233D">
<ContentPage.Content>
<StackLayout Padding="10,10,10,10">
<StackLayout VerticalOptions="Start">
<Label TextColor = "White" Text="You're having trouble sleeping." FontSize="Large" HorizontalTextAlignment="Center"></Label>
<Image Scale=".65" Source="bed" >
</Image>
</StackLayout>
<StackLayout VerticalOptions="CenterAndExpand">
<Label TextColor = "White" Text="When the kidneys aren't filtering properly, toxins stay in the blood rather than leaving the body through the urine. This can make it difficult to sleep. There is also a link between obesity and chronic kidney disease, and sleep apnea is more common in those with chronic kidney disease, compared with the general population." HorizontalTextAlignment="Center"></Label>
</StackLayout>
<StackLayout Orientation="Horizontal" VerticalOptions="EndAndExpand" >
<Button Text="Yes" Clicked="YesClicked" ClassId="1Yes" x:Name="Yes1" HorizontalOptions="FillAndExpand" BackgroundColor="#27ae60" TextColor="White" BorderRadius="0">
</Button>
<Button Text="No" Clicked="NoClicked" ClassId="1No" x:Name="No1" HorizontalOptions="FillAndExpand" BackgroundColor="#c0392b" TextColor="White" BorderRadius="0" >
</Button>
</StackLayout>
</StackLayout>
</ContentPage.Content>
</ContentPage>
Any help is much appreciated.
It will be easier if you use a Grid with 4 rows and two columns
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label TextColor = "White" Text="You're having trouble sleeping." FontSize="Large" HorizontalTextAlignment="Center" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" />
<Image Scale=".65" Source="bed" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" >
<Label TextColor = "White" Text="When the kidneys aren't filtering properly, toxins stay in the blood rather than leaving the body through the urine. This can make it difficult to sleep. There is also a link between obesity and chronic kidney disease, and sleep apnea is more common in those with chronic kidney disease, compared with the general population." HorizontalTextAlignment="Center" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2"/>
<Button Text="Yes" Clicked="YesClicked" ClassId="1Yes" x:Name="Yes1" HorizontalOptions="FillAndExpand" BackgroundColor="#27ae60" TextColor="White" BorderRadius="0" Grid.Row="3" Grid.Column="1" />
<Button Text="No" Clicked="NoClicked" ClassId="1No" x:Name="No1" HorizontalOptions="FillAndExpand" BackgroundColor="#c0392b" TextColor="White" BorderRadius="0" Grid.Row="3" Grid.Column="0" />
Try to adjust rows Hheight and width if the result is different from your needs.
For more information about grids : Microsoft docs

Embed image not showing in Xamarin.Forms

I have two images in 'Images' folder. Trying to load these images in page but image not showing on page. It does not produce any error in debug. I am checking in Xamarin live player android device.
ImageResourceExtension.cs
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using Xamarin.Forms.Internals;
namespace Buffting
{
// You exclude the 'Extension' suffix when using in Xaml markup
[Preserve(AllMembers = true)]
[ContentProperty(nameof(Source))]
public class ImageResourceExtension : IMarkupExtension
{
public string Source { get; set; }
public object ProvideValue(IServiceProvider serviceProvider)
{
if (Source == null)
return null;
// Do your translation lookup here, using whatever method you require
var imageSource = ImageSource.FromResource(Source);
return imageSource;
}
}
}
BeautySalon.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Buffting;assembly=Buffting"
x:Class="Buffting.Home.BeautySalon"
Title="Beauty Salon">
<ContentPage.Content>
<ListView x:Name="SalonList" RowHeight="370">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Frame Margin="5,5,5,-5" OutlineColor="Blue" HasShadow="true">
<Grid>
<Grid Grid.Row="0">
<Grid.RowDefinitions>
<RowDefinition Height="200" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Grid.Row="0" Grid.ColumnSpan="2" HeightRequest="200" Source="{ Binding SalonImage}" VerticalOptions="Fill" Aspect="AspectFill" />
</Grid>
<Grid Grid.Row="1" Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Grid.Row="1" Grid.Column="0" Margin="0, 40, 0, 0" Text="{ Binding SalonName }" FontSize="Large" TextColor="White" />
<Image Grid.Row="1" Grid.Column="1" x:Name="Star" Source="{local:ImageResource Buffting.Images.star_outline.png}" />
</Grid>
<Grid Grid.Row="2" Padding="0, 0, 10, 0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Text="Location:" FontAttributes="Bold" FontSize="Small" TextColor="Black" />
<Label Grid.Row="0" Grid.Column="1" Text="{ Binding Location}" />
<Label Grid.Row="1" Grid.Column="0" Text="Full Address:" FontAttributes="Bold" FontSize="Small" TextColor="Black" />
<Label Grid.Row="1" Grid.Column="1" Text="{ Binding Address}" />
<Label Grid.Row="2" Grid.Column="0" Text="Phone:" FontAttributes="Bold" FontSize="Small" TextColor="Black" />
<Label Grid.Row="2" Grid.Column="1" Text="{ Binding Phone}" />
<Label Grid.Row="3" Grid.Column="0" Text="Opening Time:" FontAttributes="Bold" FontSize="Small" TextColor="Black" />
<Label Grid.Row="3" Grid.Column="1" Text="{ Binding OpeningTime}" />
</Grid>
</Grid>
</Frame>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
</ContentPage>
I am using this code but image is not loading. I ma new in Xamarin please guide me.
It's wrong, the images are placed within each native project. For Xamarin.Forms you should place the images in the Drawables folders.
If your project is android and ios ,you finally have two images : one in iosproject/Resources and one in AndroidProject/Resources/Drawab.
see Images Doc
If you want to load your images from the shared assembly. Ensure images are set as "EmbeddedResource" (Right Click: Properties, Build Action).
You have too add each image in there native Projects. here is a sample of how it should look like:
You can use the following plugin to generate your images for iOS:
Plugin: Link
For Android:
For IOS :
You can now reference your images in your xaml :
<Image Source="star_outline.png" />
<Image Source="star_selected.png" />
UPDATE:
In your xaml change:
<Image Grid.Row="1" Grid.Column="1" x:Name="Star" Source="{local:ImageResource Buffting.Images.star_outline.png}" />
with :
<Image Grid.Row="1" Grid.Column="1" x:Name="Star" Source="star_outline.png" />
The image should appear , This answers your main question. I'm not sure why your using IMarkupExtension , your not even calling it in the xaml
I had this same problem and found the answer in this thread. Embedded images not showing
When using the ImageResourceExtension the Source property should be prefixed with the Assembly Na

show datePicker in Xamarin.Forms when click Frame Layout

I am doing an application using Xamarin.Forms. There I need to show a datePicker when clicks on a Frame layout. For that purpose I have done this.
xaml part
<Frame Margin="15,0,15,5" HasShadow="false" OutlineColor="{StaticResource TextColorBlue}" BackgroundColor="White" x:Name="selectDate" HorizontalOptions="FillAndExpand">
<StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand">
<DatePicker x:Name="datePicker" IsVisible="false" DateSelected="Handle_DateSelected" TextColor="Maroon" />
<Label Text="Date" FontAttributes="Bold" FontSize="20" HorizontalOptions="Center" TextColor="{StaticResource TextColorBlue}" />
<BoxView HorizontalOptions="FillAndExpand" BackgroundColor="Silver" HeightRequest="1" />
<Grid RowSpacing="1" ColumnSpacing="1" HorizontalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Text="Saturday" FontAttributes="Bold" FontSize="25" Grid.Row="0" Grid.Column="0" HorizontalOptions="Center" VerticalOptions="Center" TextColor="{StaticResource TextColorBlue}" />
<Label Text="May" FontAttributes="Bold" FontSize="25" Grid.Row="0" Grid.Column="1" HorizontalOptions="Center" VerticalOptions="Center" TextColor="{StaticResource TextColorBlue}" />
<Label Text="20" FontAttributes="Bold" FontSize="25" Grid.Row="1" Grid.Column="0" HorizontalOptions="Center" VerticalOptions="Center" TextColor="{StaticResource TextColorBlue}" />
<Label Text="2017" FontAttributes="Bold" FontSize="25" Grid.Row="1" Grid.Column="1" HorizontalOptions="Center" VerticalOptions="Center" TextColor="{StaticResource TextColorBlue}" />
</Grid>
</StackLayout>
<Frame.GestureRecognizers>
<TapGestureRecognizer NumberOfTapsRequired="1" Tapped="Handle_Tapped_DatePicker" />
</Frame.GestureRecognizers>
</Frame>
cs part
void Handle_Tapped_DatePicker(object sender, System.EventArgs e)
{
Debug.WriteLine("Handle_Tapped_DatePicker");
if (datePicker.IsFocused)
{
Debug.WriteLine("Yes, datePicker is focused");
datePicker.Unfocus();
}
datePicker.Focus();
}
void Handle_DateSelected(object sender, Xamarin.Forms.DateChangedEventArgs e)
{
Debug.WriteLine("e.NewDate: " + e.NewDate.ToString());
}
But nothing happening here. The datePicker is not showing. I am testing on iOS simulator. Please help me on this.
Thankfully I got the answer after some searches.
The thing is that, You need to bring the focus of datePicker through the device main UI thread. I have changed my code like this.
Device.BeginInvokeOnMainThread(() =>
{
if (datePicker.IsFocused)
datePicker.Unfocus();
datePicker.Focus();
});

Resources