动态更改 Flutter 应用程序中的应用程序文本主题
Dynamically changing the app text theme in a Flutter app
我正在使用标准的 flutter 文本主题,并利用 Theme.of(context).textTheme...
方式在我的整个应用中为特定项目设置样式。
我想提供一个用户偏好设置来调整“小”、“正常”和“大”之间的文本大小。例如,将文本大小分别缩放 x0.75、x1.0 和 x1.25。
我能够在 returns 这些值之一的用户设置屏幕上实现滑块。
现在的挑战是通知所有小部件必须使用更大的新文本大小呈现文本。
我在之前的应用程序中所做的是为文本主题使用自定义 ChangeNotifier。这个 class 有一种方法可以在其库存中的所有“样式”上设置比例,然后通知听众重建。虽然效果很好,但非常麻烦。维护甚至使用这个自定义的“Theme Provider”是可行的,但却是一种体力劳动密集型折磨。
我希望有一个简单、巧妙的方法来允许以下内容的一些变化:
MyTextSizePicker(
onChanged: (double newScalingFactor) {
Theme.of(context, listen: false).scaleTextTheme(newScalingFactor);
});
理想情况下,我不必手动重新实现 scaleTextTheme,但即使我必须这样做,最多也应该允许每个“标准”TextStyles 使用新的 fontSize 进行更新,例如一些有点
bodyText1 = bodyText1.copyWith(fontSize: baseBodyText1.fontSize * scalingFactor);
我觉得奇怪的是,flutter 中的标准主题没有方法来更新 运行 应用程序的主题。
避免在每个小部件中更改文本大小的样板的最佳选择是使用提供程序更改应用程序的主题
return ChangeNotifierProvider<ThemeProvider>(
create: (_) => ThemeProvider(),
builder: (context, _){
final ThemeProvider themeData = context.watch<ThemeProvider>();
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: themeData.theme,
onGenerateRoute: Routes.getRoute,
initialRoute: homeRoute,
);
},
),
class ThemeProvider with ChangeNotifier{
double _scale = 1;
//Or create your own theme and keep its reference somewhere
ThemeData get theme => ThemeData.light()
..textTheme.apply(fontSizeFactor: _scale)
..accentTextTheme.apply(fontSizeFactor: _scale)
..primaryTextTheme.apply(fontSizeFactor: _scale);
themeScale(double newScale) {
if(newScale == _scale) return;
_scale = newScale
notifyListeners();
}
}
然后像这样调用你的 textSizePicker
MyTextSizePicker(
onChanged: (double newScalingFactor) {
Provider.of<ThemeProvider>(context, listen: false).themeScale(newScalingFactor);
});
这将重建所有有文本的小部件,而无需您手动更改它们 style : Theme.of(context).bodyText1.copyWith(fontSize: baseBodyText1.fontSize * scalingFactor);
我正在使用标准的 flutter 文本主题,并利用 Theme.of(context).textTheme...
方式在我的整个应用中为特定项目设置样式。
我想提供一个用户偏好设置来调整“小”、“正常”和“大”之间的文本大小。例如,将文本大小分别缩放 x0.75、x1.0 和 x1.25。
我能够在 returns 这些值之一的用户设置屏幕上实现滑块。
现在的挑战是通知所有小部件必须使用更大的新文本大小呈现文本。
我在之前的应用程序中所做的是为文本主题使用自定义 ChangeNotifier。这个 class 有一种方法可以在其库存中的所有“样式”上设置比例,然后通知听众重建。虽然效果很好,但非常麻烦。维护甚至使用这个自定义的“Theme Provider”是可行的,但却是一种体力劳动密集型折磨。
我希望有一个简单、巧妙的方法来允许以下内容的一些变化:
MyTextSizePicker(
onChanged: (double newScalingFactor) {
Theme.of(context, listen: false).scaleTextTheme(newScalingFactor);
});
理想情况下,我不必手动重新实现 scaleTextTheme,但即使我必须这样做,最多也应该允许每个“标准”TextStyles 使用新的 fontSize 进行更新,例如一些有点
bodyText1 = bodyText1.copyWith(fontSize: baseBodyText1.fontSize * scalingFactor);
我觉得奇怪的是,flutter 中的标准主题没有方法来更新 运行 应用程序的主题。
避免在每个小部件中更改文本大小的样板的最佳选择是使用提供程序更改应用程序的主题
return ChangeNotifierProvider<ThemeProvider>(
create: (_) => ThemeProvider(),
builder: (context, _){
final ThemeProvider themeData = context.watch<ThemeProvider>();
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: themeData.theme,
onGenerateRoute: Routes.getRoute,
initialRoute: homeRoute,
);
},
),
class ThemeProvider with ChangeNotifier{
double _scale = 1;
//Or create your own theme and keep its reference somewhere
ThemeData get theme => ThemeData.light()
..textTheme.apply(fontSizeFactor: _scale)
..accentTextTheme.apply(fontSizeFactor: _scale)
..primaryTextTheme.apply(fontSizeFactor: _scale);
themeScale(double newScale) {
if(newScale == _scale) return;
_scale = newScale
notifyListeners();
}
}
然后像这样调用你的 textSizePicker
MyTextSizePicker(
onChanged: (double newScalingFactor) {
Provider.of<ThemeProvider>(context, listen: false).themeScale(newScalingFactor);
});
这将重建所有有文本的小部件,而无需您手动更改它们 style : Theme.of(context).bodyText1.copyWith(fontSize: baseBodyText1.fontSize * scalingFactor);