'Button text font size based on the size of the button

I would like to resize the text inside my button based on the size of my button. How can I do it?

<Button StyleClass="btnFAF" Text="Field Activity" Grid.Row="0" Grid.Column="0" x:Name="btnFAF" Clicked="btnFAF_Clicked" BorderRadius="6">
    <Button.FontFamily>
        <OnPlatform x:TypeArguments="x:String">
            <On Platform="Android" Value="OpenSans-Regular.ttf#OpenSans-Regular"/>
        </OnPlatform>
    </Button.FontFamily>
 </Button>


Solution 1:[1]

You can use the Custom Renderer

In Forms Shared Project:

public MainPage()
{
    InitializeComponent();
    Content = new StackLayout
    {
        Children = { new MyButton { Text="XXXX", WidthRequest=50, HeightRequest=20 } },
        VerticalOptions = LayoutOptions.CenterAndExpand,
        HorizontalOptions = LayoutOptions.CenterAndExpand,
    };
}

And you can define a subclass of Button:

namespace App11 {
    public class MyButton : Button {
            public MyButton() 
            { }
        }
    }

In iOS:

[assembly: ExportRenderer(typeof(MyButton), typeof(MyiOSButton))]
namespace xxx.iOS 
{
    class MyiOSButton : ButtonRenderer
    {
        public MyiOSButton()
        { }

        protected override void OnElementChanged(ElementChangedEventArgs<Button> e) 
        {
            base.OnElementChanged(e);
            if(Control != null)
            {
                Control.TitleLabel.SizeToFit();
                Control.TitleLabel.AdjustsFontSizeToFitWidth = true;
            }
        }
    }
}

In Android:

[assembly:ExportRenderer(typeof(MyButton), typeof(MyAndroidClass))]
namespace _1111111.Droid
{
    public class AutoFitButton : Android.Widget.Button
    {
        public AutoFitButton(Context context) : base(context) 
        { }

        protected override void OnDraw(Canvas canvas) 
        {
            base.OnDraw(canvas);
            SetAutoSizeTextTypeWithDefaults(AutoSizeTextType.Uniform);
        }
    }
 
    public class MyAndroidClass : ButtonRenderer
    {
        IElementController ElementController => Element as IElementController;
        public MyAndroidClass(Context context) : base(context)
        { }

        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e)
        {
            base.OnElementChanged(e);
            if(Control != null) 
            {
                SetNativeControl(new AutoFitButton(Context));
            }
        }

        protected override void OnDraw(Canvas canvas)
        {
            base.OnDraw(canvas);
        }
    }
}

Notice:the method SetAutoSizeTextTypeWithDefaults(AutoSizeTextType.Uniform) is only available after Android O (API 26).

Solution 2:[2]

Let me propose you a workaround if you are not targeting low Android versions (around < 21) where this doesn't look anti-aliased. You can create a "standart" button with a defined FontSize, then just apply Scale to it, to make it bigger: the button and the text will be scaled accordingly.

<ui:MyButton Scale="1.5" x:Name="MyBigButton"/>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Junaid Pathan
Solution 2 Nick Kovalsky