如何解决在Flutter应用中动态更改应用文本主题
我使用的是标准的Flutter文本主题,并使用Theme.of(context).textTheme...
的方式在整个应用中的特定项目上设置样式。
我想提供一个用户首选项设置,以在“小”,“普通”和“大”之间调整文本大小。例如,分别将文字大小缩放到x0.75,x1.0和x1.25。
我能够在用户设置屏幕上实现Slider,并返回这些值之一。
现在的挑战是通知所有小部件必须以更大的新文本大小呈现文本。
我在先前的应用程序中所做的是将自定义ChangeNotifier用于文本主题。此类提供一种方法来设置清单中所有“样式”的比例,然后通知侦听器进行重建。虽然效果很好,但它非常麻烦。维护甚至使用此自定义“主题提供程序”都是可行的,但这是一种人工和劳动密集的折磨。
我希望有一种简单,整洁的方式来允许以下内容的变化:
MyTextSizePicker(
onChanged: (double newScalingFactor) {
Theme.of(context,listen: false).scaleTextTheme(newScalingFactor);
});
理想情况下,我不必手动重新实现scaleTextTheme,但是即使我必须这样做,它最多也应该允许每个“标准” TextStyle用新的fontSize更新,例如某种
bodyText1 = bodyText1.copyWith(fontSize: baseBodyText1.fontSize * scalingFactor);
令人惊讶的是,标准主题上没有任何方法可以更新正在运行的应用程序的主题。
解决方法
避免改变每个小部件中文本大小的最佳选择是使用提供程序来更改应用的主题
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);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。