我在 Flutter 的每个文本小部件中使用 textScaleFactor,但是如果用户从设备设置中更改显示或字体大小。它会更改整个应用程序的所有文本小部件的大小。
有什么方法可以阻止从主功能、MaterialApp 或 ThemeData 监听设备设置中的文本大小?
我不想使用 MediaQuery,因为我的应用程序非常大,我现在无法更改每个文本小部件。
谢谢
您可以像这样覆盖系统提供的文本比例因子:
MaterialApp(
builder: (BuildContext context, Widget child) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(textScaleFactor: 1.0, ), //set desired text scale factor here
child: child,
);
},
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
这会将整个应用程序中的系统文本比例因子覆盖为您选择的因子。
但这是一个非常糟糕的做法。您不应依赖覆盖系统/辅助功能设置来修复您的用户界面。许多设备具有多种外形尺寸、屏幕分辨率、密度等。解决此问题的正确方法是创建一个响应式 UI,它可以针对不同的屏幕和设置进行良好的缩放。一个很好的起点是响应式 ui 的官方 flutter 网站,以及 auto_size_text 包,它可以为您省去很多缩放文本的麻烦。
为了空安全,请使用此代码:
MaterialApp(
builder: (BuildContext context, Widget? child) {
return MediaQuery(
data: data.copyWith(
textScaleFactor: 1.0),
child: child!,
);
},
title: 'Flutter Demo',
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
它的实现有点混乱。它以“child”作为参数,为了空安全,我们应该添加“!”到最后。只需要将此部分添加到 main.dart 中,它将应用于所有应用程序页面。完整的工作代码示例:
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
builder: (BuildContext context, Widget? child) {
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaleFactor: 1.0,
),
child: child!,
);
},
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
title: 'My Shiny App',
home: HomePage(),
);
}
}
如果您愿意,可以为其设置最小和最大比例,这是推荐的方法,如下所示:
return MaterialApp(
builder: (BuildContext context, Widget? child) {
final myMediaQuery = MediaQuery.of(context);
final definedScaleRange = mediaQueryData.textScaleFactor.clamp(0.5, 1.2);
return MediaQuery(
data: MediaQuery.of(context).copyWith(textScaleFactor: definedScaleRange),
),
child: child!,
);
},
答案已过时,因为
MediaQueryData.fromWindow
已弃用。此外,MediaQuery.of(context).copyWith(textScaleFactor: 1.0),
并不总是可取的,因为它会强制频繁重建,例如当显示键盘时。
此解决方案解决了弃用和重建问题:
@override
Widget build(BuildContext context) {
MediaQueryData windowData = MediaQueryData.fromView(View.of(context));
windowData = windowData.copyWith(
textScaleFactor: 1.0, //or whatever you want
);
return MediaQuery(
data: windowData,
child: MaterialApp(
useInheritedMediaQuery: true, //if you need it
//...
),
);
}
这会起作用
return MaterialApp(
builder: (context, child) {
//ignore system scale factor
return MediaQuery(
data: MediaQuery.of(context).copyWith(
textScaleFactor: 1.0,
),
child: child ?? Container(),
);
},