缩放嵌套的RichText小部件以实现可访问性

时间:2020-06-04 07:57:31

标签: flutter flutter-layout

我正在努力RichText处理包含其他RichText实例的嵌套范围。只要用户不更改手机的默认字体大小,它就可以正常工作。但是,如果他们改变了显示字体的大小,事情就会开始变糟。

考虑以下情况,我正在解析一些看起来像这样的HTML:

<underline><italic><bold>xxxxx</bold></italic></underline>

从概念上讲,这可以建模为TextSpanTextSpan内的TextSpan,所以我可能会有一些人为的代码,如下所示:

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final inputText = 'The quick brown fox jumped over the lazy dog. The quick brown fox jumped over the lazy dog.';
    final initialSpan = TextSpan(text: inputText, style: TextStyle(color: Colors.black));

    final boldText = _buildStyledElement(context, initialSpan, Style.bold);
    final boldItalised = _buildStyledElement(context, WidgetSpan(child: boldText), Style.italic);
    final boldItalisedUnderlined = _buildStyledElement(context, WidgetSpan(child: boldItalised), Style.underline);

    return new Scaffold(
      appBar: AppBar(title: Text('')),
      body: Column(
        children: [
          Text(inputText), // a simple baseline to compare
          boldText,
          boldItalised,
          boldItalisedUnderlined,
        ],
      ),
    );
  }

  RichText _buildStyledElement(BuildContext context, InlineSpan span, Style style) {
    // note we're not applying the style because it isn't important... the style parameter
    // is just a means of wrapping our heads around a real-world example of nesting
    return RichText(text: span);
  }
}

如您在左侧看到的那样,使用正常的字体大小看起来不错,但是在右侧,当您调整手机的字体大小时,三个RichText大小写无法缩放。

No scaling

这很容易解释...因为RichText的默认缩放比例为1.0,所以没有缩放比例。让我们通过将创建代码更改为以下内容来解决该问题:

return RichText(text: span, textScaleFactor: MediaQuery.of(context).textScaleFactor);

如下所示,普通字体看起来仍然不错,但是哇...由于RichText嵌套,事情很快就可以真正地放大(我假设它将缩放因子应用于已经缩放的子级上)。

Scaling based on device

现在,我发现的一件事是,如果我允许使用RichText的比例因子创建所有1.0小部件,然后将最外面的包装在RichText中即使用设备的比例因子,/几乎/可以正常工作。例如,删除_buildStyledElement中的缩放比例,然后将此行添加到主Column小部件中:

RichText(text: WidgetSpan(child: boldItalisedUnderlined), textScaleFactor: MediaQuery.of(context).textScaleFactor),

如您所见,在正常的字体大小下看起来不错,而对于大型字体,实际上可以缩放到正确的大小。但是,包装纸现在坏了。

Just scaling the outer widget

我假设这是因为子RichText小部件计算出的大小(因为它们使用的缩放因子为1.0)不会与总的计算空间相乘使用媒体查询的比例因子时。

那么...我想我的问题是,是否有一种方法可以真正使它与嵌套的RichText实例一起正常工作。我知道对于这个特定示例,可能还有其他一些选择……但是我说的是RichText小部件嵌入其他RichText小部件的一般情况。

任何想法都将不胜感激。抱歉,很长的帖子。

1 个答案:

答案 0 :(得分:3)

尽管没有确定的解决方案,但有一种解决方法对我的目的特别有用:

您需要将Html Widget的文本比例因子固定为1,并为HTML上的普通文本选择默认字体大小,然后将其乘以屏幕的当前比例因子(不是手动固定)。

class ExampleWidget extends StatelessWidget {
  final String data;
  ExampleWidget({this.data});
  @override
  Widget build(BuildContext context) {
    double scaleFactor = MediaQuery.of(context).textScaleFactor;
    int standardFontSize = 14;
    int h3FontSize = 18;
    return MediaQuery(
      data: MediaQueryData(textScaleFactor: 1),
      child: Html(
        data: data,
        style: {
          'body': Style(fontSize: FontSize(standardFontSize * scaleFactor)),
          'h3': Style(fontSize: FontSize(h3FontSize * scaleFactor))
          // other header fonts...
        },
      ),
    );
  }
}

缺点是每次需要新的字体大小时都需要手动实施,但这可能会解决一个紧急问题。