【问题标题】:Dynamically changing the app text theme in a Flutter app在 Flutter 应用中动态更改应用文本主题
【发布时间】:2020-12-19 00:53:51
【问题描述】:

我正在使用标准的颤振文本主题,并利用Theme.of(context).textTheme... 方式在整个应用程序中设置特定项目的样式。

我想提供一个用户偏好设置来在“小”、“正常”和“大”之间调整文本大小。例如将文本大小分别缩放 x0.75、x1.0 和 x1.25。

我能够在用户设置屏幕上实现一个 Slider,它返回其中一个值。

现在的挑战是通知所有小部件必须使用更大的新文本大小呈现文本。

我在之前的应用程序中所做的是为文本主题使用自定义 ChangeNotifier。这个类有一个方法来设置它库存中所有“样式”的比例,然后通知听众重建。虽然这很好用,但非常麻烦。维护甚至使用这个自定义的“主题提供者”是可行的,但却是一种体力劳动密集型的折磨。

我希望有一种简单、整洁的方式来允许以下内容的一些变化:

MyTextSizePicker(
  onChanged: (double newScalingFactor) {
    Theme.of(context, listen: false).scaleTextTheme(newScalingFactor);
  });

理想情况下我不必手动重新实现 scaleTextTheme,但即使我必须这样做,最多也应该允许使用新的 fontSize 更新每个“标准”TextStyles,例如某种

bodyText1 = bodyText1.copyWith(fontSize: baseBodyText1.fontSize * scalingFactor);

令我惊讶的是,flutter 中的标准 Theme 上没有方法来更新正在运行的应用程序的主题。

【问题讨论】:

    标签: flutter themes flutter-provider


    【解决方案1】:

    避免在每个小部件中更改文本大小的样板文件的最佳选择是使用提供程序来更改应用程序的主题

    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);

    【讨论】:

    • 完美。我不知道 TextTheme 上的 .apply() !太棒了!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-14
    • 1970-01-01
    • 1970-01-01
    • 2018-09-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多