如果接觸過原生開發的朋友可能知道
最初幾年官方推薦使用 sp 作爲字體大小的單位,但是事實上經過長時間實踐的情況下,大家都開始逐漸使用 dp 作爲單位
這樣使用者調整系統字體大小,app 中的文字大小就不會收到影響,出現錯誤等情況
flutter 中修改
iOS 中叫動態字體大小,對應輔助功能中的字體大小
android 中叫字體大小
當你開發完成,又遇到用戶修改系統字體大小導致某些地方錯位,甚至按鈕被擠出屏幕看不見了就是個問題了
而 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
也可查看到代碼,需要自備梯子
後記
動態字體的事情就是這樣了