I have a loop that adds a grid to a StackLayout for each patient (about 70 records). The grid has a column for a picture (the source of which is a url) and a column for the name. I thought it was the pictures that were causing the out of memory condition, but after hours of stepping through the code, I stumbled on what seems to be the culprit. If I wrap the grids in a frame, that seems to be an issue. I am using Xamarin 4.2.1.62.
I really do want a frame around each patient so I can have a border around each one. Anyone have any ideas?
For a reproducible example, create a page with a single StackLayout
<StackLayout VerticalOptions="FillAndExpand" x:Name="StackPatientList"></StackLayout>
Then, right after your InitializeComponent() call in the page, call this function:
private void InitPatients()
{
ObservableCollection<Patient> PatientsList = new ObservableCollection<Patient>();
for (int i = 0; i < 100; i++)
{
PatientsList.Add(new Patient() { FirstName = "First " + i.ToString(), LastName = "Last " + i.ToString() });
}
StackLayout oStack = new StackLayout() { };
this.StackPatientList.Children.Clear();
foreach (Patient oPat in PatientsList)
{
Grid oGrid = new Grid();
oGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(100, GridUnitType.Auto) });
oGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) });
oGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(100, GridUnitType.Absolute) });
oGrid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
Image oPatImage = new Image() { Source = oPat.Picture, WidthRequest = 100, HeightRequest = 100 };
Label oPatLabel = new Label() { Text = oPat.FullName, FontSize = 15, VerticalTextAlignment = TextAlignment.Center };
oGrid.Children.Add(oPatLabel, 0, 0);
oGrid.Children.Add(oPatImage, 1, 0);
Frame oFrame = new Frame() { OutlineColor = Color.Black, Padding = 5, VerticalOptions = LayoutOptions.FillAndExpand };
oFrame.Content = oGrid;
//this.StackPatientList.Children.Add(oGrid); // Using this works fine
this.StackPatientList.Children.Add(oFrame); // This causes an out of memory error
}
}
Using this as your Patient class:
public class Patient
{
public string LastName { get; set; }
public string FirstName { get; set; }
public string FullName { get { return LastName + ", " + FirstName; } }
public string Picture { get; set; }
}
Run it on an android device (I use an LG-G3) and you will get an out of memory error. Then comment out the line that adds the frame and un-comment the line that just adds the grid and it will work fine.
Related
I have used Segmented Control in my application. I don't know how to add two content pages to Segment control like a tabbed page. I have attached the sample file. Please give any suggestion Link for Sample Application
Sample Code:
public partial class SamplePage : ContentPage
{
SegmentedControl segControl;
SegmentedControlOption optionOne;
SegmentedControlOption optionTwo;
public SamplePage()
{
segControl = new SegmentedControl();
optionOne = new SegmentedControlOption();
optionTwo = new SegmentedControlOption();
optionOne.Text = "One";
optionTwo.Text = "Two";
segControl.Children.Add(optionOne);
segControl.Children.Add(optionTwo);
var stack = new StackLayout()
{
VerticalOptions = LayoutOptions.StartAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand,
Children = { segControl }
};
this.Content = stack;
}
}
ScreenShot Attached
Just some suggestions and explanations.
We can't put a ContentPage inside another ContentPage
It's better to use ContentView instead of ContentPage
Grid is more recommended in this scenario , since it fills with the whole Screen.
Use ValueChanged event to change the view dynamically.
Code :
Page
public partial class SegmentedAppPage : ContentPage
{
SegmentedControl segControl;
SegmentedControlOption scOptionOne;
SegmentedControlOption scOptionTwo;
Grid grid;
View1 view1 = new View1();
View2 view2 = new View2();
public SegmentedAppPage()
{
InitializeComponent();
segControl = new SegmentedControl();
segControl.SelectedValue = "One";
scOptionOne = new SegmentedControlOption();
scOptionTwo = new SegmentedControlOption();
scOptionOne.Text = "One";
scOptionTwo.Text = "Two";
segControl.Children.Add(scOptionOne);
segControl.Children.Add(scOptionTwo);
grid = new Grid();
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Auto) });
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
grid.Children.Add(segControl, 0, 0);
grid.Children.Add(view1, 0, 1);
this.Content = grid;
segControl.ValueChanged += SegControl_ValueChanged;
}
private void SegControl_ValueChanged(object sender, EventArgs e)
{
SegmentedControl control = sender as SegmentedControl;
if(control.SelectedValue is "One")
{
grid.Children.Remove(view2);
grid.Children.Add(view1,0,1); //This line
}
else if (control.SelectedValue is "Two")
{
grid.Children.Remove(view1);
grid.Children.Add(view2, 0, 1); //This line
}
this.Content = grid;
}
}
ContentView
public class View1 : ContentView
{
public View1()
{
Content = new StackLayout
{
BackgroundColor = Color.Green,
Children = {
new Label { Text = "View1" }
}
};
}
}
To set default value on segmentedControl , modify code in SegmentedControlRenderers
protected override void OnElementChanged(ElementChangedEventArgs<SegmentedControl> e)
{
base.OnElementChanged(e);
var segmentedControl = new UISegmentedControl();
for (var i = 0; i < e.NewElement.Children.Count; i++)
{
segmentedControl.InsertSegment(e.NewElement.Children[i].Text, i, false);
}
segmentedControl.ValueChanged += (sender, eventArgs) => {
e.NewElement.SelectedValue = segmentedControl.TitleAt(segmentedControl.SelectedSegment);
};
segmentedControl.SelectedSegment = 0; // add this line
SetNativeControl(segmentedControl);
}
Test
I am having a hard time refreshing a listView. I've tried using ObservableCollection instead of List for contacts but it didn't help. Can someone points me to the right direction please? Any help would be very much appreciated.
ContactListPage.cs file (This is the default page. Add Contact button loads up NewContactPage.)
public class ContactListPage : ContentPage
{
public ListView listView = new ListView();
public List<Contact> contacts { get; set; }
public ContactListPage()
{
Button button = new Button
{
Text = "Add Contact",
Margin = new Thickness(0, 0, 10, 0)
};
button.Clicked += OnButtonClicked;
StackLayout buttonLayout = new StackLayout { Orientation = StackOrientation.Horizontal, VerticalOptions = LayoutOptions.Center,
Children =
{
new Label {Text = "Contact List", FontSize = 30, FontAttributes = FontAttributes.Bold | FontAttributes.Italic, Margin = new Thickness(10,0,0,0)},
new Label {Text = "", FontSize = 30, FontAttributes = FontAttributes.Bold | FontAttributes.Italic, HorizontalOptions = LayoutOptions.CenterAndExpand},
button
}
};
contacts = new List<Contact>
{
// Add some contacts
new Contact("Jason", "Bourne", "Family"),
new Contact("Sunny", "An", "Family Dog"),
new Contact("Jenny", "Bahn", "Family"),
new Contact("Joshua", "Brown", "Work")
};
// Set up listview
listView.ItemsSource = contacts;
listView.ItemTemplate = new DataTemplate(typeof(TextCell));
listView.ItemTemplate.SetBinding(TextCell.TextProperty, "FullName");
listView.ItemTemplate.SetBinding(TextCell.DetailProperty, "ContactType");
listView.HeightRequest = (40 * contacts.Count);
// Add things to the stacklayout
StackLayout layout = new StackLayout();
layout.Children.Add(buttonLayout);
layout.Children.Add(listView);
Content = layout;
void OnButtonClicked(object sender, EventArgs args)
{
Navigation.PushAsync(new NewContactPage());
};
}
}
Contact.cs file
public class Contact
{
// constructor
public Contact(string firstName, string lastName, string contactType)
{
FirstName = firstName;
LastName = lastName;
ContactType = contactType;
}
// properties
public string FirstName { get; set; }
public string LastName { get; set; }
public string ContactType { get; set; }
public string FullName
{
get
{
return FirstName + " " + LastName;
}
set
{
FullName = value;
}
}
}
NewContactPage.cs file (Save button seems to be working. I've used Debug.WriteLine to see the list of contacts prior and after adding a new contact. Return button suppose to refresh the contactPage.listView.ItemSource with the latest contents of contacts but it doesn't.)
public NewContactPage()
{
ContactListPage contactPage = new ContactListPage();
// Setup tableview
EntryCell firstName = new EntryCell {Label = "First Name:", Keyboard = Keyboard.Default};
EntryCell lastName = new EntryCell {Label = "Last Name:", Keyboard = Keyboard.Default};
EntryCell contactType = new EntryCell {Label = "Contact Type:", Keyboard = Keyboard.Default};
Label firstLabel = new Label { Text = "", FontSize = 10, FontAttributes = FontAttributes.Bold | FontAttributes.Italic, HorizontalOptions = LayoutOptions.CenterAndExpand};
Label secondLabel = new Label {Text = "", FontSize = 10, FontAttributes = FontAttributes.Bold | FontAttributes.Italic, HorizontalOptions = LayoutOptions.CenterAndExpand};
TableView tableView = new TableView {VerticalOptions = LayoutOptions.Start, Intent = TableIntent.Form,
Root = new TableRoot("Table Title") {
new TableSection ("Add a New Contact") {
firstName,
lastName,
contactType
}
}
};
// Setup buttons
Button saveContactButton = new Button {Text = "Save Contact", WidthRequest = 150, Margin = new Thickness(50, 0, 0, 0)};
saveContactButton.Clicked += saveContactButtonClicked;
Button returnButton = new Button {Text = "Return", WidthRequest = 150, Margin = new Thickness(10, 0, 50, 0)};
returnButton.Clicked += returnButtonClicked;
StackLayout buttonLayout = new StackLayout {Orientation = StackOrientation.Horizontal, VerticalOptions = LayoutOptions.Start,
Children =
{
saveContactButton,
new Label {Text = "", FontSize = 30, FontAttributes = FontAttributes.Bold | FontAttributes.Italic, HorizontalOptions = LayoutOptions.CenterAndExpand},
returnButton
}
};
Content = new StackLayout {Children = { tableView, buttonLayout, firstLabel, secondLabel }};
void saveContactButtonClicked(object sender, EventArgs e)
{
try
{
foreach (var yeah in contactPage.contacts)
{
Debug.WriteLine(yeah.FirstName.ToString());
}
// Add new contact to list
contactPage.contacts.Add(new Contact(firstName.Text.ToString(), lastName.Text.ToString(), contactType.Text.ToString()));
foreach (var yeah in contactPage.contacts)
{
Debug.WriteLine(yeah.FullName.ToString());
}
firstName.Text = String.Empty;
lastName.Text = String.Empty;
contactType.Text = String.Empty;
DisplayAlert("Success", "New contact has been added.", "OK");
}
catch(Exception ex)
{
Debug.WriteLine("Exception: {0}", ex);
}
};
void returnButtonClicked(object sender, EventArgs e)
{
contactPage.listView.ItemsSource = null;
contactPage.listView.ItemsSource = contactPage.contacts;
Navigation.PopAsync();
};
}
}
As Jason said, in the constructor of NewContactPage you are creating a new instance of ContactListPage which is completely different than the page you came from (and will return to upon PopAsync()).
To make it so you are adding the new contact to the correct page, I suggest passing in the your ContactListPage in the constructor of the NewContactPage:
public NewContactPage(ContactListPage contactPage)
{
//As a side note it's probably better practice to make
//contactPage a private variable for the NewContactPage class
//...
}
Then in your ContactListPage change the button click method to pass in the page:
void OnButtonClicked(object sender, EventArgs args)
{
Navigation.PushAsync(new NewContactPage(this));
};
Hope this helps!
I am using FlowListView To set gallery view in my xamarin forms application, with following code..
public class Page1 : ContentPage
{
public Page1()
{
ObservableCollection<ItemModel> List = new ObservableCollection<ItemModel>();
string[] images = {
"https://farm9.staticflickr.com/8625/15806486058_7005d77438.jpg",
"https://farm5.staticflickr.com/4011/4308181244_5ac3f8239b.jpg",
"https://farm8.staticflickr.com/7423/8729135907_79599de8d8.jpg",
"https://farm3.staticflickr.com/2475/4058009019_ecf305f546.jpg",
"https://farm6.staticflickr.com/5117/14045101350_113edbe20b.jpg",
"https://farm2.staticflickr.com/1227/1116750115_b66dc3830e.jpg",
"https://farm8.staticflickr.com/7351/16355627795_204bf423e9.jpg",
"https://farm1.staticflickr.com/44/117598011_250aa8ffb1.jpg",
"https://farm8.staticflickr.com/7524/15620725287_3357e9db03.jpg",
"https://farm9.staticflickr.com/8351/8299022203_de0cb894b0.jpg",
};
int number = 0;
for (int n = 0; n < 20; n++)
{
for (int i = 0; i < images.Length; i++)
{
number++;
var item = new ItemModel()
{
ImageUrl = images[i],
FileName = string.Format("image_{0}.jpg", number),
};
List.Add(item);
}
}
FlowListView listView = new FlowListView()
{
FlowColumnTemplate = new DataTemplate(typeof(ListCell)),
SeparatorVisibility = SeparatorVisibility.None,
HasUnevenRows = true,
FlowColumnMinWidth = 110,
FlowItemsSource = List,
};
listView.FlowItemTapped += (s, e) =>
{
var item = (ItemModel)e.Item;
if (item != null)
{
App.Current.MainPage.DisplayAlert("Alert", "Tapped {0} =" + item.FileName, "Cancel");
}
};
Content = new StackLayout
{
Children = {
listView
}
};
}
}
public class ItemModel
{
public string ImageUrl { get; set; }
public string FileName { get; set; }
}
public class ListCell : View
{
public ListCell()
{
CachedImage IconImage = new CachedImage
{
HeightRequest = 100,
Aspect = Aspect.Fill,
DownsampleHeight = 100,
DownsampleUseDipUnits = false,
LoadingPlaceholder = "image_loading.png",
ErrorPlaceholder = "image_error.png"
};
IconImage.SetBinding(CachedImage.SourceProperty, "ImageUrl");
Label NameLabel = new Label
{
Opacity = 0.5,
HorizontalOptions = LayoutOptions.Fill,
HorizontalTextAlignment = TextAlignment.Center,
VerticalOptions = LayoutOptions.End,
};
NameLabel.SetBinding(Label.TextProperty, "FileName");
Grid grd = new Grid
{
Padding = 3,
ColumnDefinitions = {
new ColumnDefinition { Width = new GridLength (1, GridUnitType.Star) },
},
RowDefinitions = {
new RowDefinition { Height=GridLength.Star},
},
};
grd.Children.Add(IconImage,0,0);
grd.Children.Add(NameLabel, 0, 1);
}
}
i added all the dependency of FlowListView, FFImage etc,
This above code just showing blank screen, Not displaying any data...
You're ListCell has nothing to show.
Append the existing lines to set the content to the grid in your custom ViewCell.
grd.Children.Add(IconImage,0,0);
grd.Children.Add(NameLabel, 0, 1);
Content = grd; <--- add this line
Also have you done the following as per advice from the author? i.e. You've added the nuget library to the platforms in addition to the PCL and added the corresponding initialisation code for the library?
You must add this line to your platform specific project (AppDelegate.cs, MainActivity.cs, etc) before you use FFImageLoading:
CachedImageRenderer.Init();
This is what I got in my IOS:
[Register("AppDelegate")]
public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
{
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
FFImageLoading.Forms.Touch.CachedImageRenderer.Init(); <---- this line
LoadApplication(new App());
return base.FinishedLaunching(app, options);
}
}
I have an app with a Xamarin forms listview that's fed by an ObservableCollection to list user games I fetch from my server. The first time I load it up it works just fine. If I modify that existing ObservableCollection in any way my app crashes with a NullException. I've narrowed it down to my custom ViewCell (GameCell) and I've posted that below. If I comment one line out toward the bottom:
this.SetBinding(IsEnabledProperty, "Enabled");
Then it no longer crashes updating the ObservableCollection, but then I no longer get the functionality to have some cells enabled and some cells disabled. I'm guessing it's trying to set the isEnabled property to a cell that no longer exists because it's been removed on my reload. Any ideas how do this with out crashing? BTW, this works fine on Android, just not on iOS
using System;
using Xamarin.Forms;
using FFImageLoading.Forms;
namespace Upwords
{
public class GameCell : ViewCell
{
public GameCell ()
{
var icon = new CachedImage () {
Aspect = Aspect.AspectFit,
HorizontalOptions = LayoutOptions.Fill,
VerticalOptions = LayoutOptions.Fill,
BackgroundColor = AppStyle.IconColor,
IsVisible = false,
};
icon.SetBinding (CachedImage.SourceProperty, "Icon");
icon.SetBinding (CachedImage.LoadingPlaceholderProperty, "IconPlaceholder");
icon.SetBinding (CachedImage.ErrorPlaceholderProperty, "IconPlaceholder");
icon.SetBinding (CachedImage.WidthRequestProperty, "Height");
icon.SetBinding (CachedImage.HeightRequestProperty, "Height");
icon.Success += (object sender, CachedImageEvents.SuccessEventArgs e) => {
icon.FadeAnimationEnabled = false;
if(icon.Source.GetType() == typeof(Xamarin.Forms.UriImageSource)) {
icon.BackgroundColor = Color.Transparent;
}
};
icon.PropertyChanged += (object sender, System.ComponentModel.PropertyChangedEventArgs e) => {
if(icon.Source != null)
icon.IsVisible = true;
else
icon.IsVisible = false;
};
var nameLabel = new Label () {
FontFamily = "Helvetica",
FontAttributes = FontAttributes.Bold,
FontSize = Device.GetNamedSize (NamedSize.Medium, typeof(Label)),
TextColor = Color.Black,
};
nameLabel.SetBinding (Label.TextProperty, "Name");
//Hide label if it's blank
nameLabel.PropertyChanged += (object sender, System.ComponentModel.PropertyChangedEventArgs e) => {
if(nameLabel.Text == "")
nameLabel.IsVisible = false;
else
nameLabel.IsVisible = true;
};
var detailsLabel = new Label () {
FontFamily = "Helvetica",
FontSize = Device.GetNamedSize (NamedSize.Small, typeof(Label)),
FontAttributes = FontAttributes.Bold,
TextColor = Color.FromHex ("#666"),
IsVisible = false,
};
detailsLabel.SetBinding (Label.TextProperty, "Details");
//Hide label if it's blank
detailsLabel.PropertyChanged += (object sender, System.ComponentModel.PropertyChangedEventArgs e) => {
if(string.IsNullOrEmpty( detailsLabel.Text ) )
detailsLabel.IsVisible = false;
else
detailsLabel.IsVisible = true;
};
var textLayout = new StackLayout {
Padding = new Thickness (5, 0, 0, 0),
Spacing = 0,
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.CenterAndExpand,
Children = { nameLabel, detailsLabel}
};
var optionSwitch = new Switch() {
HorizontalOptions = LayoutOptions.End,
VerticalOptions = LayoutOptions.Center,
IsVisible = false,
};
optionSwitch.SetBinding (Switch.IsVisibleProperty, "IsSwitch");
var statusLayout = new StackLayout {
Padding = new Thickness (10, 10, 10, 10),
Orientation = StackOrientation.Horizontal,
HorizontalOptions = LayoutOptions.FillAndExpand,
Children = { icon, textLayout, optionSwitch}
};
statusLayout.SetBinding (StackLayout.HeightRequestProperty, "Height");
var separatorBox = new BoxView {
HeightRequest = 1,
HorizontalOptions = LayoutOptions.FillAndExpand,
BackgroundColor = Color.FromRgb(.75,.75,.75),
};
separatorBox.SetBinding (BoxView.HeightRequestProperty, "SeparatorHeight");
var separatorBoxLayout = new StackLayout {
Padding = new Thickness (50, 0, 0, 0),
HorizontalOptions = LayoutOptions.FillAndExpand,
Children = { separatorBox }
};
var cellLayout = new StackLayout {
Spacing = 0,
Padding = new Thickness (0, 0, 0, 0),
Orientation = StackOrientation.Vertical,
HorizontalOptions = LayoutOptions.FillAndExpand,
BackgroundColor = Color.White,
Opacity = 1.0,
Children = { statusLayout, separatorBoxLayout }
};
cellLayout.SetBinding (StackLayout.OpacityProperty, "Opacity");
var headerFrame = new ListViewLabel () {
};
headerFrame.SetBinding (ListViewLabel.IsVisibleProperty, "IsLabel");
headerFrame.SetBinding (ListViewLabel.TextProperty, "Name");
headerFrame.SetBinding (ListViewLabel.HeightRequestProperty, "Height");
headerFrame.PropertyChanged += (object sender, System.ComponentModel.PropertyChangedEventArgs e) => {
if(headerFrame.IsVisible)
cellLayout.IsVisible = false;
else
cellLayout.IsVisible = true;
};
var paddedLayout = new StackLayout {
Spacing = 0,
Orientation = StackOrientation.Horizontal,
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand,
Children = { headerFrame, cellLayout }
};
this.SetBinding(IsEnabledProperty, "Enabled");
this.View = paddedLayout;
}
}
public class GameCellData
{
public string Icon { get; set; }
public string IconPlaceholder { get; set; }
public string Name { get; set; }
public string Details { get; set; }
public int Height { get; set; }
public int SeparatorHeight { get; set; }
public bool Enabled { get; set; }
public double Opacity { get; set; }
public bool IsLabel { get; set; }
public bool IsSwitch { get; set; }
}
}
Turns out updating to latest packages fixed the crash.
So I have a horizontal scrollview that I'm trying to dynamically populate when the user takes a certain action. The items I am throwing into the view each contain 4 labels that are using custom fonts. When I try to add about 10 of these items it lags for about 1.5 seconds on android and 1 second on IOS. If I take the custom font out then its about 1 second on each platform. If I take out 3 of the labels and only display one then its almost instantaneous. Is there any known reason for the lag? And is there any way around it so I can still use a custom font without a huge lag?
Here's a quick sample I made that pretty much does what I'm doing in my app. However, my app has more stuff so the lag isn't quite as bad here but it is still very noticeable
public class App : Application
{
public int count;
public ScrollView scroll, scroll2, scroll3;
public App ()
{
count = 1;
scroll = new ScrollView {
VerticalOptions = LayoutOptions.Center,
Orientation = ScrollOrientation.Horizontal
};
scroll2 = new ScrollView {
VerticalOptions = LayoutOptions.Center,
Orientation = ScrollOrientation.Horizontal
};
Button button = new Button(){
Text = "click",
};
button.Clicked += (sender, e) => AddStuff();
Button button2 = new Button(){
Text = "click",
};
button2.Clicked += (sender, e) => AddStuff2();
MainPage = new ContentPage {
BackgroundColor = Color.White,
Content = new StackLayout{
Children={
button,
scroll,
button2,
scroll2
}
}
};
}
//this one is instantaneous
public void AddStuff()
{
StackLayout stack = new StackLayout () {
Orientation = StackOrientation.Horizontal,
HorizontalOptions = LayoutOptions.FillAndExpand,
HeightRequest = 200,
};
for (int i = 0; i < 11; i++)
stack.Children.Add (
new StackLayout(){
Children = {
new Label (){TextColor = Color.Blue, Text = "Size: ", WidthRequest = 100 },
}
}
);
scroll.Content = stack;
count++;
}
//this one takes forever
public void AddStuff2()
{
StackLayout stack = new StackLayout () {
Orientation = StackOrientation.Horizontal,
HorizontalOptions = LayoutOptions.FillAndExpand,
HeightRequest = 200,
};
for (int i = 0; i < 11; i++)
stack.Children.Add (
new StackLayout(){
Children = {
new Label (){TextColor = Color.Blue, Text = "Size: ", WidthRequest = 100 },
new Label (){TextColor = Color.Blue, Text ="" + count*i, WidthRequest = 100 },
new Label (){TextColor = Color.Blue, Text = "Size: ", WidthRequest = 100 },
new Label (){TextColor = Color.Blue, Text ="" + count*i, WidthRequest = 100 }
}
}
);
scroll2.Content = stack;
count++;
}
}
and the custom font label for droid
[assembly: ExportRenderer (typeof (Label), typeof (CustomFontLabel_Droid))]
namespace df.Droid
{
public class CustomFontLabel_Droid:LabelRenderer
{
protected override void OnElementChanged (ElementChangedEventArgs<Xamarin.Forms.Label> e) {
base.OnElementChanged (e);
var label = (TextView)Control;
Typeface font = Typeface.CreateFromAsset (Forms.Context.Assets, "SourceSansPro-Semibold.otf");
label.Typeface = font;
}
}
}
Just incase anyone else is having a similar problem, if you make a static typeface property in the android MainActivity instead of calling createFromAsset inside the Label.OnElementChanged function every time then it gets rid of the extra lag on android.
CustomFontLabel_Droid.cs
[assembly: ExportRenderer (typeof (Label), typeof (CustomFontLabel_Droid))]
namespace df.Droid
{
public class CustomFontLabel_Droid:LabelRenderer
{
protected override void OnElementChanged (ElementChangedEventArgs<Xamarin.Forms.Label> e) {
base.OnElementChanged (e);
var label = (TextView)Control;
// this guy slows things down-> Typeface font = Typeface.CreateFromAsset (Forms.Context.Assets, "SourceSansPro-Semibold.otf");
label.Typeface = MainActivity.semiBoldFont;
}
}
}
MainActivity.cs
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
{
public static Typeface semiBoldFont = null;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
global::Xamarin.Forms.Forms.Init (this, bundle);
LoadApplication (new App ());
semiBoldFont = Typeface.CreateFromAsset (Forms.Context.Assets, "SourceSansPro-Semibold.otf");
}
}