flutter取消動態字體大小

如果接觸過原生開發的朋友可能知道

最初幾年官方推薦使用 sp 作爲字體大小的單位,但是事實上經過長時間實踐的情況下,大家都開始逐漸使用 dp 作爲單位

這樣使用者調整系統字體大小,app 中的文字大小就不會收到影響,出現錯誤等情況

flutter 中修改

iOS 中叫動態字體大小,對應輔助功能中的字體大小

20190312152451.png

android 中叫字體大小

20190312152635.png

當你開發完成,又遇到用戶修改系統字體大小導致某些地方錯位,甚至按鈕被擠出屏幕看不見了就是個問題了

而 flutter 中沒有單位的概念,我們應該如何實現這個功能呢

在 flutter 中,是由 MediaQuery 來實現對應功能的

var data = MediaQuery.of(context);
data.textScaleFactor; //這個就是對應的動態字體大小,我們只需要『修改』這個值就可以了

修改自然是不可能的,這東西都是 final 的,我們要做的就是 flutter 中的通用做法

class NoScaleTextWidget extends StatelessWidget {
  final Widget child;

  const NoScaleTextWidget({
    Key key,
    @required this.child,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaxScaleTextWidget(
      max: 1.0,
      child: child,
    );
  }
}

class MaxScaleTextWidget extends StatelessWidget {
  final double max;
  final Widget child;

  const MaxScaleTextWidget({
    Key key,
    this.max = 1.2,
    @required this.child,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    var data = MediaQuery.of(context);
    var scale = math.min(max, data.textScaleFactor);
    return MediaQuery(
      data: data.copyWith(textScaleFactor: scale),
      child: child,
    );
  }
}

我這裏的做法就是這樣,創建一個組件,在內部修改這個值,然後把你的控件『包』起來

這裏可以是你的 Scaffold,Text 等等的 widget

不過這樣要修改的地方太多,而且後面不好改

我們可以用一個小技巧,使用 MaterialApp 的 builder 屬性

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      ....
      builder: (ctx, w) {
        return MaxScaleTextWidget(
            max: 1.0,
            child: w,
        );
      },
    );
  }
}

在這個 builder 中這麼寫,就可以修改你 app 中的所有控件不受動態字體大小的影響了

我在 github 有一個 gisthttps://gist.github.com/CaiJingLong/d28208f569b44f39dd572a7e8f455912 也可查看到代碼,需要自備梯子

後記

動態字體的事情就是這樣了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章