Expanding the size of ListView cell on tap - xamarin

I'm trying to implement a solution to increase the size of a ListView Cell when tapped using Xamarin Forms (and custom renderers if required).
I'm still pretty new to C#, and the idea of data binding is still a little unclear to me, however, it seems like that is the way to go to solve this problem (perhaps something along the lines of binding the Height / HeightRequest properties of the cell?).
My attempts thus far have been unsuccessful.
If anyone could give me a push in the right direction it would be much appreciated.
Thank you!

ViewCell does not expose Height as a BindableProperty in Xamarin.Forms 1.4.2x
However if you create your own BindableProperty in your Model you can achieve changing the height still as shown below:-
Model:-
public class MenuItem2 : BindableObject
{
public static readonly BindableProperty TextProperty = BindableProperty.Create<MenuItem2, string>(p => p.Text, default(string));
public static readonly BindableProperty CellHeightProperty = BindableProperty.Create<MenuItem2, int>(p => p.CellHeight, default(int));
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public int CellHeight
{
get { return (int)GetValue(CellHeightProperty); }
set { SetValue(CellHeightProperty, value); }
}
}
XAML:-
<StackLayout>
<Button x:Name="cmdButton1" Text="Change Cell Heights" Clicked="cmdButton1_Clicked"/>
<ListView x:Name="lstItems" />
</StackLayout>
XAML Code-Behind:-
lstItems.HasUnevenRows = true;
lstItems.ItemTemplate = new DataTemplate(typeof(Classes.MenuCell2));
//
lstItems.ItemsSource = new List<MenuItem2>
{
new MenuItem2(),
new MenuItem2(),
new MenuItem2(),
new MenuItem2(),
};
If you don't set .HasUnevenRows you will not be able to change the cell height.
void cmdButton1_Clicked(object sender, EventArgs e)
{
Random objRandom = new Random();
//
var objItems = lstItems.ItemsSource;
//
foreach (MenuItem2 objMenuItem in objItems)
{
int intNewCellHeight = objRandom.Next(80, 160);
objMenuItem.CellHeight = intNewCellHeight;
objMenuItem.Text = "Cell Height = " + intNewCellHeight.ToString();
}
}
Custom ViewCell:-
public class MenuCell2 : ViewCell
{
public MenuCell2()
{
Label objLabel = new Label
{
YAlign = TextAlignment.Center,
TextColor = Color.Yellow,
};
objLabel.SetBinding(Label.TextProperty, new Binding("Text"));
StackLayout objLayout = new StackLayout
{
Padding = new Thickness(20, 0, 0, 0),
Orientation = StackOrientation.Horizontal,
HorizontalOptions = LayoutOptions.StartAndExpand,
Children = { objLabel }
};
Frame objFrame_Inner = new Frame
{
Padding = new Thickness(15, 15, 15, 15),
HeightRequest = 36,
OutlineColor = Color.Accent,
BackgroundColor = Color.Blue,
Content = objLayout,
};
Frame objFrame_Outer = new Frame
{
Padding = new Thickness(0, 0, 0, 10),
Content = objFrame_Inner
};
View = objFrame_Outer;
this.BindingContextChanged += MenuCell2_BindingContextChanged;
}
void MenuCell2_BindingContextChanged(object sender, EventArgs e)
{
MenuItem2 objMenuItem = (MenuItem2)this.BindingContext;
objMenuItem.PropertyChanged += objMenuItem_PropertyChanged;
}
void objMenuItem_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case "CellHeight":
this.Height = (this.BindingContext as MenuItem2).CellHeight;
(this.View as Frame).ForceLayout();
break;
}
}
Remember to call ForceLayout on the root element of the ViewCell's View property, so it can redraw correctly.
This will give you a result something similar to the following (tested only on WindowsPhone at present):-
In order to do it on a ViewCell being tapped, on the XAML Page add:-
lstItems.ItemTapped += lstItems_ItemTapped;
and then change the model for the item to something like this:-
void lstItems_ItemTapped(object sender, ItemTappedEventArgs e)
{
(e.Item as MenuItem2).CellHeight = 200;
}

Xamarin now has an official example of doing this right within xaml and xaml code behind:
Overview:
https://developer.xamarin.com/samples/xamarin-forms/UserInterface/ListView/DynamicUnevenListCells/
Code:
https://github.com/xamarin/xamarin-forms-samples/tree/master/UserInterface/ListView/DynamicUnevenListCells

Related

Activity Indicator not working in Xamarin.Forms

I have an activity indicator designed inside a absolute layout. Based on a button click event, I try to show and hide the activity indicator alternatively. But due to some reason, I cannot see my activity Indicator.Any help will be greatly appreciated!!! Thanks in advance.
This is my .xaml.cs class:
public partial class PBTestPage : ContentPage
{
private bool _pbIndicator;
public PBTestPage()
{
InitializeComponent();
}
public bool PBIndicator{
get{
return _pbIndicator;
}set{
_pbIndicator = value;
OnPropertyChanged();
}
}
protected override void OnAppearing()
{
base.OnAppearing();
var parentLayout = new AbsoluteLayout();
var stackContent = new StackLayout();
AbsoluteLayout.SetLayoutFlags(stackContent,AbsoluteLayoutFlags.PositionProportional);
AbsoluteLayout.SetLayoutBounds(stackContent,new Rectangle(0f,0f,AbsoluteLayout.AutoSize,AbsoluteLayout.AutoSize));
var activityIndicator = new ActivityIndicator
{
Color = Color.Black,
IsRunning = PBIndicator,
IsVisible = PBIndicator
};
AbsoluteLayout.SetLayoutFlags(activityIndicator, AbsoluteLayoutFlags.PositionProportional);
AbsoluteLayout.SetLayoutBounds(activityIndicator, new Rectangle(.5, .5, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize));
var button = new Button
{
Text="Click",
VerticalOptions=LayoutOptions.CenterAndExpand,
HorizontalOptions=LayoutOptions.CenterAndExpand,
};
button.Clicked += OnClicked;
stackContent.Children.Add(button);
parentLayout.Children.Add(stackContent);
parentLayout.Children.Add(activityIndicator);
Content = parentLayout;
}
private void OnClicked(object sender, EventArgs e)
{
if(PBIndicator==false){
PBIndicator = true;
}else{
PBIndicator = false;
}
}
}
I'm inferring you're intending to use bindings by the use of OnPropertyChanged, so it's a good time to start do it.
I've made some changes in your code and I guess it will work properly now. The changes are:
Moved the layout creation to the constructor (I can't see create the whole same layout on every time the page is shown as a good choice );
The OnClicked event just invert the value of the property, no need to check it before with an if;
Using Bindings to handle the ActivityIndicator's properties state;
Set true to PBIndicator property on the OnAppearing event.
This is the changed code:
public partial class PBTestPage : ContentPage
{
private bool _pbIndicator;
public bool PBIndicator
{
get { return _pbIndicator; }
set
{
_pbIndicator = value;
OnPropertyChanged();
}
}
public PBTestPage()
{
InitializeComponent();
var parentLayout = new AbsoluteLayout();
var stackContent = new StackLayout();
AbsoluteLayout.SetLayoutFlags(stackContent, AbsoluteLayoutFlags.PositionProportional);
AbsoluteLayout.SetLayoutBounds(stackContent, new Rectangle(0f, 0f, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize));
var activityIndicator = new ActivityIndicator
{
Color = Color.Black
};
activityIndicator.SetBinding(ActivityIndicator.IsRunningProperty, new Binding(nameof(PBIndicator)));
activityIndicator.SetBinding(ActivityIndicator.IsVisibleProperty, new Binding(nameof(PBIndicator)));
activityIndicator.BindingContext = this;
AbsoluteLayout.SetLayoutFlags(activityIndicator, AbsoluteLayoutFlags.PositionProportional);
AbsoluteLayout.SetLayoutBounds(activityIndicator, new Rectangle(.5, .5, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize));
var button = new Button
{
Text = "Click",
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand,
};
button.Clicked += OnClicked;
stackContent.Children.Add(button);
parentLayout.Children.Add(stackContent);
parentLayout.Children.Add(activityIndicator);
Content = parentLayout;
}
protected override void OnAppearing()
{
base.OnAppearing();
PBIndicator = true;
}
private void OnClicked(object sender, EventArgs e)
{
PBIndicator = !PBIndicator;
}
}
Let me know if it works. I hope it helps.
Try this one
private void OnClicked(object sender, EventArgs e)
{
if(PBIndicator==false){
activityIndicator.IsRunning=true;
}else{
activityIndicator.IsRunning=false;
}
}

How to Add Content Page to Segment Control in IOS Xamarin.Forms

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

iOS UIMenuController Custom Renderer for Xamarin Forms

I am trying to create a custom renderer so that a context menu is displayed when a user clicks a button. I have it working in Android and UWP but iOS is proving more difficult. When I click the button, everything runs with no errors but the UIMenuController is not displayed, although I cannot click the button again almost as though the view containing the button has overlaid the screen preventing access to the button. I've tried attaching the menu controller to the button, the ContextMenuView.
Here's the custom Xamarin Forms View -
public class ContextMenuView : View
{
public EventHandler MenuRequested;
public void RequestMenu(object sender)
{
if(MenuRequested != null)
{
MenuRequested(sender, EventArgs.Empty);
}
}
}
The ContextMenuView is instantiated from the click event of a button on Main.xaml. Main.xaml consists of an AbsoluteLayout that contains the button being clicked. Here's the click event of the button -
private void ContextMenuButton_Clicked(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine("Click");
var button = sender as Button;
if (_popupMenu == null)
{
_popupMenu = new ContextMenuView();
Rectangle menuPosition = new Rectangle { X = button.X, Y = button.Y, Width = 50, Height = 50 };
_popupMenu.Layout(((Button)sender).Bounds);
AbsLayout.Children.Add(_popupMenu, menuPosition);
_popupMenu.IsVisible = true;
}
else
{
Rectangle menuPosition = new Rectangle { X = button.X, Y = button.Y + button.Height, Width = 50, Height = 50 };
_popupMenu.Layout(((Button)sender).Bounds);
}
_popupMenu.RequestMenu(sender);
}
And the iOS renderer -
public class ContextMenuViewRendererIOS : ViewRenderer<ContextMenuView, UIView>
{
private UIView _nativeControl;
private ContextMenuView _xamarinControl;
private Xamarin.Forms.AbsoluteLayout _container;
private UIView _iosView;
private nfloat _height;
private nfloat _width;
protected override void OnElementChanged(ElementChangedEventArgs<ContextMenuView> e)
{
base.OnElementChanged(e);
if (Control == null)
{
if (e.NewElement != null)
{
_xamarinControl = e.NewElement;
_xamarinControl.MenuRequested += OnMenuRequested;
}
_height = UIScreen.MainScreen.Bounds.Height;
_width = UIScreen.MainScreen.Bounds.Width;
_nativeControl = new UIView(new CGRect(0, 0, _width, _height));
SetNativeControl(_nativeControl);
}
}
private void OnMenuRequested(object sender, EventArgs e)
{
try
{
var _menu = UIMenuController.SharedMenuController;
BecomeFirstResponder();
var iterm = new UIMenuItem("John", new ObjCRuntime.Selector("MenuItemAction:"));
_menu.MenuItems = new[] { iterm };
_menu.SetTargetRect(new CGRect(10, 10, 100, 100), _nativeControl);
_menu.MenuVisible = true;
}
catch (Exception ex)
{
throw;
}
}
[Export("MenuItemAction:")]
private void MenuItemAction(UIMenuController controller)
{
System.Diagnostics.Debug.WriteLine("MenuItemAction");
}
}
Thanks in advance.
The custom renderer needs to override CanBecomeFirstResponder and CanPerform(Selector action, NSObject withSender) and return true from both.

PulltoRefresh + await FadeTo+TranslateTo animation combination Crash on Xamarin.forms

I'm making app with using Xamarin.forms PCL.
I'm having really hard time to solve this issue.
I've spent several days but couldn't solve.
I'm using this nuget
PullToRefresh
https://github.com/jamesmontemagno/Xamarin.Forms-PullToRefreshLayout
xabre ble plugin
https://github.com/xabre/xamarin-bluetooth-le
When I use this at the same time AND Add some animation on the page.
It gives this runtime exception when I try to refresh. (It happens very rare like 1 time on 10 times)
The Crash happens ONLY iOS.
It's very rare. You can try to refresh more than 10 times. You will see.
It happens only actual iOS Device.
Foundation.MonoTouchException: Objective-C exception thrown. Name:
NSGenericException Reason: *** Collection <__NSSetM: 0x14feb8b0> was
mutated while being enumerated.
I know well what this is and when this happen.
It happens when I try to access deleted item on list or different thread.
So I made very simple source code to look this issue simply.
I don't have any list or array on my code.
Well, it happens again.
https://github.com/myallb/test_pulltorefresh
This is my sample source code for reproducing this issue. If you can help me, please look this code.
The Crash happens ONLY iOS.
It's very rare. You can try to refresh more than 10 times. You will see.
It happens only actual iOS Device.
Thanks so much.
Full source code
using Xamarin.Forms;
using Plugin.BLE.Abstractions.Contracts;
using Plugin.BLE;
using Plugin.BLE.Abstractions.EventArgs;
using System;
using System.Diagnostics;
using Refractored.XamForms.PullToRefresh;
using System.Threading.Tasks;
namespace test
{
public partial class testPage : ContentPage
{
public static IAdapter Adapter { set; get; }
public PullToRefreshLayout RefreshView = null;
AbsoluteLayout layout;
public testPage()
{
InitializeComponent();
Adapter = CrossBluetoothLE.Current.Adapter;
if (Adapter != null)
{
Adapter.DeviceAdvertised += OnEvent_DeviceAdvertised;
Adapter.DeviceConnected += OnEvent_DeviceConnected;
Adapter.DeviceConnectionLost += OnEvent_DeviceConnectionLost;
Adapter.DeviceDisconnected += OnEvent_DeviceDisconnected;
Adapter.DeviceDiscovered += OnEvent_DeviceDiscovered;
Device.StartTimer(TimeSpan.FromSeconds(5), Timer_ScanDevice);
}
else {
}
layout = new AbsoluteLayout()
{
BackgroundColor = Color.Purple,
};
ScrollView scrollview = new ScrollView()
{
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
Content = layout
};
RefreshView = new PullToRefreshLayout
{
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
Content = scrollview,
RefreshColor = Color.Red,
RefreshCommand = new Command(RefreshStart)
};
RefreshView.IsPullToRefreshEnabled = true;
Content = RefreshView;
Device.StartTimer(new TimeSpan(0, 0, 1), ani);
}
bool ani()
{
Label z = new Label()
{
Text = "Z",
TextColor = Color.White,
FontAttributes = FontAttributes.Bold,
FontSize = new Random().Next(22, 35)
};
AbsoluteLayout.SetLayoutBounds(z, new Rectangle(0.67 + new Random().Next(0, 10) / 100.0, 0.13 + new Random().Next(0, 10) / 100.0, 40, 40));
AbsoluteLayout.SetLayoutFlags(z, AbsoluteLayoutFlags.PositionProportional);
layout.Children.Add(z);
Device.BeginInvokeOnMainThread(async () =>
{
Task t1 = z.FadeTo(0, 3500);
Task t2 = z.TranslateTo(0, -70, 3500, Easing.SinInOut);
await Task.WhenAll(t1, t2);
layout.Children.Remove(z);
});
return true;
}
void RefreshStart()
{
Debug.WriteLine("RefreshStart");
if (RefreshView != null)
RefreshView.IsRefreshing = true;
Device.BeginInvokeOnMainThread(async () =>
{
await Task.Delay(20);
Debug.WriteLine("RefreshEnd");
RefreshView.IsRefreshing = false;
});
}
bool Timer_ScanDevice()
{
Adapter.StartScanningForDevicesAsync();
return true;
}
void OnEvent_DeviceAdvertised(object sender, DeviceEventArgs a)
{
Debug.WriteLine("OnEvent_DeviceAdvertised");
}
void OnEvent_DeviceDiscovered(object sender, DeviceEventArgs a)
{
Debug.WriteLine("OnEvent_DeviceDiscovered");
}
void OnEvent_DeviceConnected(object sender, DeviceEventArgs a)
{
Debug.WriteLine("OnEvent_DeviceConnected");
}
void OnDeviceProcessError(IDevice device, string message)
{
Debug.WriteLine("OnDeviceProcessError");
}
void OnEvent_DeviceConnectionLost(object sender, DeviceErrorEventArgs a)
{
Debug.WriteLine("OnEvent_DeviceConnectionLost");
}
void OnEvent_DeviceDisconnected(object sender, DeviceEventArgs a)
{
Debug.WriteLine("OnEvent_DeviceDisconnected");
}
}
}

xamarin forms dynamically adding custom font labels to scrollview is extremely slow

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");
}
}

Resources