Xamarin Android Xamarin.Forms

Xamarin.Forms Android中避免字體隨系統設定改變

張阿鬼 2018/12/31 15:42:50
1931

Xamarin.Forms Android中避免字體隨系統設定改變


簡介

Android中避免字體隨系統設定改變

作者

張朝銘


主題

Xamarin.Forms Android中避免字體隨系統設定改變

作者:

Steven

版本/產出日期:

V1.0/2018.12.10

 
前言
  Android系統本身提供了更改字大小的設定,更改字型大小的同時,可能也會導致
原本APP中的排版亂掉,造成使用者閱讀上的困難。
 
在Xamarin.Forms專案中,使用原本預設的畫面,並將其改為18大小字體。
    <StackLayout Padding="0,64,0,0">
        <Label Text="Welcome to Xamarin.Forms!"
               FontSize="18"
               TextColor="Red"
               HorizontalOptions="Center"/>
    </StackLayout>
 
執行程式後,開啟系統設定更改自型大小,再切回APP時可以看到字型放大導致換行
 
 
 
  於Android開發中,字型大小所使用的單位通常為SP,在使用此單位的情況下,字型會
隨著系統設定的字型大小變化,Xamarin.Forms使用的控制項預設使用的單位也都
是SP。如果要避免自型隨著系統變化,可將字型大小的單位替換為DP
 
  以上方的範例來說,我們使用了Label控制項,因此可以透過使用Renderer的方式來複寫
原本控制項的行為。如下程式碼中,建立了一個MyLabelRenderer控制項,並重新撰寫設定
自型大小的單位。
    public class MyLabelRenderer : LabelRenderer
    {
        public MyLabelRenderer(Context context) : base(context)  { }
        protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
        {
            base.OnElementChanged(e);

            //抓取控制項上的字形設定,並重新設定原本的單位為DP
            if (this.Control != null && this.Element != null)
                this.Control.SetTextSize(Android.Util.ComplexUnitType.Dip, Convert.ToSingle(this.Element.FontSize));
        }
    }

 

再次執行程式,可以看到字型大小已經不會被系統設定所影響

 

  這樣的方式雖然可以避免字型大小被系統影響,但如果使用的控制項一多,
就必需得針對每一種不同的控制項撰寫其Renderer,像是Button、Entry等...。

  其實還有更快的方式,可以一次設定所有的字型大小都不被系統影響,只要設定
APP本身的FontScale,將其調整為1倍,就能避免被系統放大的問題(所以上面白做了XD)

由於Xamarin普通情況下只有一個Activity,所以在該Activity的OnCreate實做以下程式碼即可

        protected override void OnCreate(Bundle savedInstanceState)
        {

            Configuration configuration = Resources.Configuration;
            configuration.FontScale = 1f;
            //0.85 小字型, 1 標準大小, 1.15 大字型,1.3 有點大字型 ,1.45超級大 
            DisplayMetrics metrics = new DisplayMetrics();
            this.WindowManager.DefaultDisplay.GetMetrics(metrics);
            metrics.ScaledDensity = configuration.FontScale * metrics.Density;
            this.BaseContext.Resources.UpdateConfiguration(configuration, metrics);

            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(savedInstanceState);
            global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
            LoadApplication(new App());
        }


當然通常我們會希望APP內的所有字體大小都不會被系統影響,
但客戶端常常有很奇怪的需求,像是不影響跑版的部分都要正常放大之類的,
這時候就適用於第一種作法,針對不想被放大的部分獨立建立一個Xamarin.Forms控制項來使用。
第二種做法也適用於Xamarin.Android or 原生Android開發喔!

PS:iOS的系統也有字型大小,但不影響APP內的設定,所以沒有此問題。

 

範例連結

 

 

 

張阿鬼