简体   繁体   English

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

[英]Scaling nested RichText widgets for accessibility

I'm wrestling with how RichText handles nested spans that contain other RichText instances.我正在研究RichText如何处理包含其他RichText实例的嵌套跨度。 It works fine as long as the user doesn't change the phone's default font size.只要用户不更改手机的默认字体大小,它就可以正常工作。 But if they have changed the display font size, things start going awry.但如果他们改变了显示字体大小,事情就会开始出错。

Consider the case where I'm parsing some HTML that looks like:考虑我正在解析一些 HTML 的情况,如下所示:

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

Conceptually this can be modelled as a TextSpan inside a TextSpan inside a TextSpan , so I might have some contrived code that looks like:从概念上讲,这可以建模为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);
  }
}

As you can see on the left, it looks great with normal font size but on the right, the three RichText cases don't scale when you adjust the phone's fonts size.正如您在左侧看到的,正常字体大小看起来很棒,但在右侧,当您调整手机的 fonts 大小时,三个RichText案例不会缩放。

无缩放

That's easy to explain though... because the default scaling factor for a RichText is 1.0 so there's no scaling.不过这很容易解释……因为RichText的默认缩放因子是1.0 ,所以没有缩放。 Let's fix that by changing the creation code to look like:让我们通过将创建代码更改为如下所示来解决这个问题:

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

As you can see below, the normal font still looks good, but woah... things scale up real quickly due to the RichText nesting (I'm assuming it is applying the scale factor onto already scaled children).正如您在下面看到的那样,普通字体看起来仍然不错,但是哇……由于RichText嵌套,事情真的迅速扩大了(我假设它将比例因子应用于已经缩放的孩子)。

基于设备的缩放

Now, one thing I've found is that if I allow all the RichText widgets to be created using a scale factor of 1.0 , and then wrap the outermost in a RichText that is using the device's scale factor, it /almost/ works.现在,我发现的一件事是,如果我允许使用1.0的比例因子创建所有RichText小部件,然后将最外面的小部件包装在使用设备比例因子的RichText中,它/几乎/可以工作。 For example, remove the scaling in _buildStyledElement and add this row into the main Column widget:例如,删除_buildStyledElement中的缩放并将此行添加到主Column小部件中:

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

As you can see, things look good at the normal font size and actually scale to the correct size for large fonts.如您所见,正常字体大小看起来不错,实际上缩放到大 fonts 的正确大小。 However, the wrapping is now broken.然而,包装现在被打破了。

只是缩放外部小部件

I'm assuming that this is because the size that is calculated by the child RichText widgets (because they are using a scale factor of 1.0 ) doesn't marry up with the total calculated space when using the media query's scale factor.我假设这是因为在使用媒体查询的比例因子时,子RichText小部件计算的大小(因为它们使用的比例因子为1.0 )与计算的总空间不匹配。

Sooo... I guess my question is whether there is a way to actually get this to work properly with nested RichText instances.太好了......我想我的问题是是否有办法让它与嵌套的RichText实例一起正常工作。 I know that for this specific example there may be some other options... but I'm talking about the general case where RichText widgets embed other RichText widgets.我知道对于这个特定的示例,可能还有其他一些选项......但我说的是RichText小部件嵌入其他RichText小部件的一般情况。

Any thoughts would be much appreciated.任何想法将不胜感激。 Sorry for the long post.对不起,很长的帖子。

Regardless of not having a definite solution there's a workaround that I found particularly useful for my purpose:尽管没有明确的解决方案,但我发现有一种解决方法对我的目的特别有用:

You need to set the text scale factor for the Html Widget fixed to 1, and choose a default font size for your average text on the HTML the multiply it to the current scale factor of the screen (not the fixed manually).您需要将 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...
        },
      ),
    );
  }
}

The downside is needing to manually implement every time you need a new font size but it might solve an urgent problem.缺点是每次需要新字体大小时都需要手动实现,但这可能会解决紧急问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM