【问题标题】:Scaling nested RichText widgets for accessibility缩放嵌套的 RichText 小部件以实现可访问性
【发布时间】:2020-06-04 07:57:31
【问题描述】:

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

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

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

从概念上讲,这可以建模为 TextSpan 内的 TextSpan 内的 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 案例不会缩放。

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

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

正如您在下面看到的,普通字体看起来仍然不错,但是哇……由于RichText 嵌套,事情真的迅速扩大了(我假设它将比例因子应用于已经缩放的孩子)。

现在,我发现的一件事是,如果我允许使用 1.0 的比例因子创建所有 RichText 小部件,然后将最外面的小部件包裹在使用设备比例的 RichText因素,它/几乎/有效。例如,删除_buildStyledElement 中的缩放并将这一行添加到主Column 小部件中:

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

如您所见,正常字体大小看起来不错,实际上缩放到大字体的正确大小。然而,包装现在被打破了。

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

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

任何想法将不胜感激。抱歉,帖子太长了。

【问题讨论】:

标签: flutter flutter-layout


【解决方案1】:

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

您需要将 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...
        },
      ),
    );
  }
}

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

【讨论】:

  • 我可以看到这可能如何解决缩放问题...在这种情况下您的文本是否正确换行?我所有的调查都发现,将最里面的比例因子设置为 1.0,然后用单个(正确的)MediaQuery 比例因子换行将导致 a) 正确缩放的文本,但 b) 文本不会在正确的边界处换行。当然,我没有专门测试更改字体大小......我只是在研究如何操作 textScaleFactor。你的技术看起来确实是一个很好的解决方法
  • 是的,由于文本边界不再超出屏幕,因此换行按预期工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-10-18
  • 2018-01-16
  • 1970-01-01
  • 2018-12-25
  • 2018-06-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多