XAMARIN: cross platform FontFamily - android

I need to specify different FontFamily for different Labels in my app. I need to use the default fonts (e.g. Roboto for Android and Helvetica for iOS) with their modifications (e.g. Light, Medium, Bold). As far as I understand I should be using Roboto-Light and Helvetica-Light to get the Light version of the fonts (same for Medium and Bold).
In addition to this requirement I need to set the fonts in XAML (like described in documentation) so I end up with this code
<StackLayout BackgroundColor="#F8F8F8" Padding="0, 20, 0, 0">
<Label Text="Black" TextColor="#000000" >
<Label.FontSize>
<OnPlatform x:TypeArguments="x:Double"
iOS="17"
Android="16"
WinPhone="16" />
</Label.FontSize>
<Label.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<OnPlatform.iOS>Helvetica-Black</OnPlatform.iOS>
<OnPlatform.Android>Roboto-Black</OnPlatform.Android>
<OnPlatform.WinPhone></OnPlatform.WinPhone>
</OnPlatform>
</Label.FontFamily>
</Label>
<Label Text="Light" TextColor="#000000">
<Label.FontSize>
<OnPlatform x:TypeArguments="x:Double"
iOS="17"
Android="16"
WinPhone="16" />
</Label.FontSize>
<Label.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<OnPlatform.iOS>Helvetica-Light</OnPlatform.iOS>
<OnPlatform.Android>Roboto-Light</OnPlatform.Android>
<OnPlatform.WinPhone></OnPlatform.WinPhone>
</OnPlatform>
</Label.FontFamily>
</Label>
<Label Text="Medium" TextColor="#000000" >
<Label.FontSize>
<OnPlatform x:TypeArguments="x:Double"
iOS="17"
Android="16"
WinPhone="16" />
</Label.FontSize>
<Label.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<OnPlatform.iOS>Helvetica-Medium</OnPlatform.iOS>
<OnPlatform.Android>Roboto-Medium</OnPlatform.Android>
<OnPlatform.WinPhone></OnPlatform.WinPhone>
</OnPlatform>
</Label.FontFamily>
</Label>
<Label Text="Bold" TextColor="#000000">
<Label.FontSize>
<OnPlatform x:TypeArguments="x:Double"
iOS="17"
Android="16"
WinPhone="16" />
</Label.FontSize>
<Label.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<OnPlatform.iOS>Helvetica-Bold</OnPlatform.iOS>
<OnPlatform.Android>Roboto-Bold</OnPlatform.Android>
<OnPlatform.WinPhone></OnPlatform.WinPhone>
</OnPlatform>
</Label.FontFamily>
</Label>
However, the result in Android is unexpected. The FontFamily of the different Labels is not changed. They all look the same.
The same code in iOS works as expected
My question is: How to get the Roboto-Light, Roboto-Medium and Roboto-Bold fonts in my Android app if following XAMARIN documentation does not work?

Update:
I did not see that you were using API 18 / 4.3 the first time (in the title bar of your emulator), thought you were loading them as custom assets for older android versions. Since roboto is the default font since 4.1, you can use them as:
sans-serif
sans-serif-light
sans-serif-condensed
sans-serif-thin (4.2+)
Original:
https://developer.xamarin.com/guides/cross-platform/xamarin-forms/working-with/fonts/
Xamarin.Forms for Android does not currently expose the ability to set
the font to a custom font file, so custom renderers are required. When
writing the renderer for the Android platform, create a Typeface
instance that references a custom font file that has been added to the
Assets directory of the application (with Build Action: AndroidAsset).
[assembly: ExportRenderer (typeof (MyLabel), typeof (MyLabelRenderer))]
namespace WorkingWithFonts.Android {
public class MyLabelRenderer : LabelRenderer {
protected override void OnElementChanged (ElementChangedEventArgs<Label> e) {
base.OnElementChanged (e);
var label = (TextView)Control; // for example
Typeface font = Typeface.CreateFromAsset (Forms.Context.Assets, "SF Hollywood Hills.ttf");
label.Typeface = font;
}
}
}

I did overwrite the default Renderer for all views I needed it for.
That way you can use XAML code like you intended to:
<Label FontFamily="Arial" Text="Hi there" />
Here is an example for Label.
[assembly: ExportRenderer (typeof (Label), typeof (MyLabelRenderer))]
namespace MyApp.Droid
{
public class MyLabelRenderer : LabelRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
if ( !String.IsNullOrEmpty(Element.FontFamily) )
Control.Typeface = Typeface.CreateFromAsset(Forms.Context.Assets, "Fonts/" + Element.FontFamily + ".otf");
}
}
}
Of course you need to map that to the location where you embedded the custom font. In my case Assets/Fonts/Arial.otf.

Please use below render, to load custom font in label, please make sure that you will put your font file in fonts folder in assets folder of android project to define similar path for all platform
[assembly: ExportRenderer(typeof(Label), typeof(CustomLabelRenderer))]
namespace MyApp.Droid.Renderer
{
public class CustomLabelRenderer : LabelRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
if (!String.IsNullOrEmpty(e.NewElement.FontFamily))
Control.Typeface = Typeface.CreateFromAsset(Forms.Context.Assets, "Fonts/" + Element.FontFamily);
}
}
}
xaml of label control, please make sure that font file is available in font folder
<Label FontFamily="Roboto-Light.ttf" Text="Hi there" />

2020 Update, Xamarin.Forms 4.5 now supports custom fonts embedded in one place (shared UI project) and exported via ExportFont attribute: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/text/fonts#use-a-custom-font - iOS, Android and UWP.
For macOS and WPF you still have to go longer path as described below.
As of 2018, in Xamairn.Forms, there's no need for platform renderers. The steps are:
Download TTF files and bundle them as resources with each platform project.
Reference the fonts from within Xamarin.Forms shared project, taking into account the peculiarities of each platform (naming conventions for addressing resources and font families).
Apply the fonts to Xamarin.Forms controls.
Here's detailed description on how to add and apply custom fonts in macOS, WPF and Android.

Related

Set Entry Cursor visibility // color

i want to create like a "hidden entry" which I use in a data loading screen to preload debit cards after going through a band reader.
My problem it's that i cannot hidden the entry cursor and they see on the screen that "someone it's typing" when they read the card with the band reader.
My code:
<Entry x:Name="cardToRead"
Text="{Binding card}"
InputTransparent="True"
TextColor="Transparent" />
I want to hide the following (purple line cursor):
Is there any property i'm missing, don't found any solution to this! thanks
UPDATE:
Actual solution (not appropriate):
<Entry x:Name="cardToRead"
Text="{Binding card}"
InputTransparent="True"
TextColor="Transparent"
WidthRequest=1 />
Cfun upload the best actual solution to solve this if your android api is higher than 29
You can use a custom Entry:
CustomEntry
internal class CustomEntry : EntryHandler
{
public CustomEntry()
{
}
protected override void ConnectHandler(AppCompatEditText platformView)
{
base.ConnectHandler(platformView);
platformView.ShowSoftInputOnFocus = false;
//platformView.SetCursorVisible(false); //not sure why it is not working
//replaced by this approah:
#if ANDROID29_0_OR_GREATER
platformView.SetTextCursorDrawable(Resource.Drawable.invisible_cursor);
#else
//code to handle it for API< 29, check link in edit section of my answer
#endif
}
}
MauiProgram.cs
#if ANDROID
builder.ConfigureMauiHandlers((handlers) =>
{
handlers.AddHandler(typeof(Entry), typeof(CustomEntry));
}
#endif
invisible_cursor.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#android:color/transparent"></solid>
</shape>
EDIT
SetTextCursorDrawable() was introduced in API29+, to support earlier Android version I invite you to take a look at set textCursorDrawable programmatically, you can handdle that case in the #else of #if ANDROID29_0_OR_GREATER (code above edited).

Is it possible to embed Android.VideoView in Xamarin Forms ContentView

I need to create a mobile app that have to run on android 7.0 - 9.0 and the latest iOS
So in my VS 2017 15.9.6 on Windows 10 I try to use Xamarin.Forms 3.4 in a shared project as a container for a native Android.VideoView.
I try to figure out how to do that, since the Mono.Android examples don't use Xamarin.Forms. So, do I need a kind of #ifdef in the xaml file, to embedd ths Android VideoView? Or am I completely wrong with that approach?
Using a Shared Projects, you can define the native views in XAML and then access them in the code behind (which is basically a requirement since native Android|iOS controls are not directly bindable and most have method calls for setting up features that would not available via XAML (i.e. a VideoView has a .SetVideoURI method that has no Xamarin-based wrapper property so you have to execute that method to play a video).
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:androidWidget="clr-namespace:Android.Widget;assembly=Mono.Android;targetPlatform=Android"
xmlns:androidGraphics="clr-namespace:Android.Graphics;assembly=Mono.Android;targetPlatform=Android"
xmlns:androidContext="clr-namespace:Forms40Shared.Droid;assembly=Forms40Shared.Android;targetPlatform=Android"
x:Class="Forms40Shared.NativeEmbedPage" >
<ContentPage.Content>
<StackLayout Margin="20">
<androidWidget:TextView x:Arguments="{x:Static androidContext:MainActivity.Instance}" Text="Welcome to Forms!" TextSize="24" View.HorizontalOptions="Center" >
<androidWidget:TextView.Typeface>
<androidGraphics:Typeface x:FactoryMethod="Create">
<x:Arguments>
<x:String>cursive</x:String>
<androidGraphics:TypefaceStyle>Normal</androidGraphics:TypefaceStyle>
</x:Arguments>
</androidGraphics:Typeface>
</androidWidget:TextView.Typeface>
</androidWidget:TextView>
<ContentView x:Name="contentView" HorizontalOptions="FillAndExpand" VerticalOptions="Center" HeightRequest="200" >
<androidWidget:VideoView x:Arguments="{x:Static androidContext:MainActivity.Instance}" />
</ContentView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
Note: Do not enable XamlCompilation at the global assembly level or on XAML pages that contain native views as it will not work (and there are not errors during compiling or runtime, the views just do not show up as they have been stripped out)...
MainActivity
[Activity(Label ~~~~
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
internal static MainActivity Instance { get; private set; }
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
Instance = this;
~~~
}
Code Behind:
#if __ANDROID__
var videoView = (contentView as NativeViewWrapper).NativeView as VideoView;
videoView.SetVideoURI(Android.Net.Uri.Parse($"android.resource://{Android.App.Application.Context.PackageName}/raw/fireplace"));
videoView.Start();
#elif __IOS__
~~~
#endif
Output:
https://msdn.microsoft.com/en-us/magazine/mt790186.aspx

How to create progress bar with rounded corners / Edge in Xamarin forms

I need the expert help. I am struggling to create the ProgressBar with rounded corner in Xamarin Form. I have searched on google and found the couple of post by using the layer property ex. "Layer.CornerRadius = 5" but my code does not support it.
How to make a progress bar with rounded corners in Xamarin forms.
(The above example not supported)
How can I create the rounded Edge of the progress bar?
Sample Code (TestControls.xaml usnig XamarinForm):-
<?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:Test.Mobile"
xmlns:ffimageloadingsvg="clr-namespace:FFImageLoading.Svg.Forms;assembly=FFImageLoading.Svg.Forms"
x:Class="Test.Mobile.UI.TestControls">
<ContentPage.Content>
<Grid Grid.Column="1" Margin="0" Padding="0" BackgroundColor= "LightYellow" >
<ProgressBar x:Name="pb_ProgressBar" Margin="70,0,30,0" Progress="0.0" WidthRequest="300" HeightRequest="20" ProgressColor="DarkSlateBlue" VerticalOptions="Center" BackgroundColor="AntiqueWhite"></ProgressBar>
</Grid>
</ContentPage.Content>
</ContentPage>
and Code behind file as
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Test.Mobile.UI
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class TestControls : ContentPage
{
public TestControls ()
{
InitializeComponent ();
Device.BeginInvokeOnMainThread(async () =>
{
await pb_ProgressBar.ProgressTo(1.0, 10000, Easing.Linear);
});
}
}
}
Please help me how to make a progress bar with rounded corners in Xamarin forms?
I can not use xmlns:android="schemas.android.com/apk/res/android";. The device android tablet will be use offline and no internet access.
This is not library, you could refer to the question:
Why this line xmlns:android=“http://schemas.android.com/apk/res/android” must be the first in the layout xml file?
As NitroG42 said, in XML, xmlns declares a Namespace. In fact, when you do:
<LinearLayout android:id>
</LinearLayout>
Instead of calling android:id, the xml will use http://schemas.android.com/apk/res/android:id to be unique. Generally this page doesn't exist (it's a URI, not a URL), but sometimes it is a URL that explains the used namespace.
The namespace has pretty much the same uses as the package name in a Java application.
You could refer to the documentation:
Uniform Resource Identifier (URI)
A Uniform Resource Identifier (URI) is a string of characters which identifies an Internet Resource.
The most common URI is the Uniform Resource Locator (URL) which identifies an Internet domain address. Another, not so common type of URI is the Universal Resource Name (URN).

Using i18n string resources in Nativescript Android

I'm pretty new to nativescript. I'm trying to figure out how to use the string values from the strings.xml so i can localize my app.
My layout looks like this.
<StackLayout class="page">
<label [text]="#string/a_value"></label>
<Label text="Hello world with tap!" class="yellow"></Label>
<button text="Tap me my friend" (tap)="tapTheButton()" class="red"></button>
<label [text]="text" class="blue"></label>
</StackLayout>
The #string/a_value should get the string from the res/values/strings.xml file.
Any help is welcome!
#string/string_name is not a valid notation when describing NativeScript layouts as it's a strictly Android way of interpolating strings.
You could probably access the resource manager (https://developer.android.com/reference/android/content/Context.html#getResources()) and get the string value for string with name a_value, and then data bind that to your label. That would only work on Android.
There is a NativeScript plugin done by the community that aims to make internationalization abstract, so that it works for both Android and iOS - nativescript-i18n.

is there any strings.xml like file in windows phone 8?

I've just started Windows phone 8 development with previous experience of Android Development.
I was just searching if there is any strings.xml like file in windows phone 8 where we can keep strings and specially color codes. Yes i want to keep my own color codes in windows phone 8 project so that i may refer these colors in my Pages XML and in code.
Suggestions are highly appreciated.
Special color codes can be placed in your App.xaml file in the resources part.
Use like the following:
<Application.Resources>
<SolidColorBrush x:Key="ColorWhite"
Color="#FFFFFFFF" />
<ImageBrush x:Key="BackGroundBrush"
ImageSource="SplashScreenImage.jpg" />
<Style x:Key="MyPageStyle"
TargetType="phone:PhoneApplicationPage">
<Setter Property="Background">
<Setter.Value>
<ImageBrush ImageSource="Background_WindowsPhone.png"
Stretch="UniformToFill" />
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
In your page you might then use the following:
<phone:ApplicationPage Style="{StaticResource MyPageStyle">
<Grid Background="{StaticResource BackGroundBrush}">
<TextBlock Text="Hi"
Foreground="{StaticResource ColorWhite}" />
</Grid>
</phone:ApplicationPage>

Categories

Resources