如何正确管理Flutter应用程序中的全局textScaleFactor?

问题描述 投票:0回答:4

Flutter 应用程序对系统大文本做出反应,使所有文本小部件都变得非常大。 我想限制文本小部件的 textScaleFactor,但我想在全局范围内执行此操作,而不是在我正在使用的每个文本小部件中。

现在启用大文本后,我遇到了类似的异常

flutter:══╡渲染库捕获异常 ╞═══════════════════════════════════════ ══════════ ════════颤动: 布局期间抛出以下消息:flutter: A RenderFlex 底部溢出 14 个像素。

正确的做法是什么? 一种方法是创建一些包装器小部件而不是使用文本,但也许可以通过其他方式解决?

image 1image 2

flutter dart font-size
4个回答
38
投票

此解决方案是在 Google I/O'19 期间提出的(大约 20 分钟):

MaterialApp(
  builder: (BuildContext context, Widget child){
    final MediaQueryData data = MediaQuery.of(context);
    return MediaQuery(
      data: data.copyWith(
        textScaleFactor: data.textScaleFactor * (_isPassive ? 2 : 1)
      ),
      child: child,
    );
  },

如果您希望所有内容都有固定的

textScaleFactor
,您可以将
data.textScaleFactor * (_isPassive ? 2 : 1)
替换为单个数字。
1.0
将使您的设计始终遵循您的
fontSize


8
投票

您可以设置一个限制,之后就不需要像某些苹果应用程序那样进行扩展。

MaterialApp(
  builder: (BuildContext context, Widget child) {
    final MediaQueryData data = MediaQuery.of(context);
    return MediaQuery(
      data: data.copyWith(
        textScaleFactor: data.textScaleFactor > 2.0 ? 2.0 : data.textScaleFactor),
        child: child,
       );
    },
  debugShowCheckedModeBanner: false,
  title: 'Flutter app',
)

此外,我添加了 2 个函数来计算不同情况下的大小。

  1. 对于任何 textScaleFactor,始终返回固定的文本大小:
double getFixedSize(double textSize) {
  return textScaleFactor != 1.0 ? textSize / textScaleFactor : textSize;
}

例如,您可以将其用于应用程序标题文本。

  1. 返回缩放后的textSize,直到未达到特定比例,该比例由第二个 maxScaleFactor 参数设置:
double getScaledOrMaxSize(double textSize, double maxScaleFactor) {
 return textScaleFactor > maxScaleFactor
   ? textSize * maxScaleFactor / textScaleFactor
   : textSize;
}

这可以用于已经很大的标题,您不需要进一步增加它们。

我希望这可以帮助您为视障人士制作优秀的应用程序,同时仍然保持它们的美观。


3
投票

要限制应用程序中所有页面的textScaleFactor,您可以执行此操作。

MaterialApp
小部件包裹您的
MediaQuery
,并使用从
MediaQueryData
创建的所需
window
数据。

并将

useInheritedMediaQuery
设置为
true

@override
Widget build(BuildContext context) {
  MediaQueryData windowData =
      MediaQueryData.fromWindow(WidgetsBinding.instance!.window);
  windowData = windowData.copyWith(
    textScaleFactor:
        windowData.textScaleFactor > 1.4 ? 1.4 : windowData.textScaleFactor,
  );
  return MediaQuery(
    data: windowData,
    child: MaterialApp(
      useInheritedMediaQuery: true,

      //...
    ),
  );
}


0
投票

答案已过时,因为

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
      //...
    ),
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.