BUG|Flutter Text组件和国际化

2022-11-04  本文已影响0人  厘米姑娘

发现问题

新版本引入了一个新勋章,测试走查其多语言时发现,泰文版勋章名没有一行展示而是换行了,如图所示:



因为其他语言没问题、泰文版其他勋章名也是正常的,所以第一反应是有问题的泰文是不是误加了换行符?经查并没有。而且在限制勋章名Text组件最多展示一行且按照末尾打点后,原本换到第二行的内容也被打点掉了:



这时尝试给Text一个最大宽度,没有任何变化:
return ConstrainedBox(
  constraints: BoxConstraints(maxWidth: 150),
  child: Text(...),
)

接着尝试给Text一个固定宽度,此时终于能正常一行展示了:

return Container(
  width: 150,
  child: Text(...),
);

但这不符合设计,Text后面紧挨着一个小问号,要求Text是自适应宽度的,因此要给Text一个实际宽度才行,但仅算出来的宽度还不行,要多加一点宽度才可以:

final painter = TextPainter(
  textDirection: TextDirection.ltr,
  maxLines: 1,
  text: TextSpan(
    text: ...,
    style: ...,
  ),
);
painter.layout(minWidth: 0, maxWidth: 150);
return Container(
  width: painter.width + 2, // 2就是额外宽度
  child: Text(...),
);

最终效果如图:


定位原因

本以为这个问题算是解决了,在自测时突然发现好几处都有类似问题,比如这个页面圈出来的几处泰文,如果限制了最大行数会表现为提前打点、未限制时会表现为莫名换行,且只有泰文有问题:


这些泰文的相同点是最后一个字符都包含 -์,为验证的确是该符号引起,做了如下测试:

那是否只有-์符号会导致错误呢?wiki-泰文字一文了解在泰文共包含这些字母:

其中,红框圈出的被称为组合符号(Combining Character),即可以加在前一个字母之上:

经过测试,这16个组合符号中有4个会导致显示异常(前四个):

其实也不难猜到,因为这4个符号明显超出底部辅音字母宽度,且超出部分能在后一个辅音字母的空间中显示。因此,如果它们不在最后一个,实际宽度就等于测量宽度(辅音字母宽度之和);如果处于最后一个,实际宽度就大于测量宽度,导致换行或打点。

解决办法

这里提供几种解决思路:
1、直接修改翻译,或在文本后加一个空格即可,可以快速修复线上问题
2、优化Text组件,兼容泰文这几个特殊符号处于最后一个的情况
3、设置字体,如Google提供的这一款泰文字体 Google Fonts-Noto Serif Thai 可以调整组合字符的显示区域,使之不超出辅音字母。

总结

突然发现最近三篇BUG系列都是多语言问题,在解决问题过程中也学习各个地区语言的与众不同,也是很有意思的经历了~

上一篇下一篇

猜你喜欢

热点阅读