Sur*_*gch 14 custom-widgets dart flutter mongolian-vertical-script
该TextDirection文档说:
Flutter旨在满足使用世界上当前使用的任何语言编写的应用程序的需求,无论它们使用从右到左还是从左到右的书写方向。Flutter不支持其他书写模式,例如竖排文本或Boustrophedon文本,因为这些模式很少在计算机程序中使用。(添加了重点)
Flutter不仅不支持垂直文本,而且将来也不会正式支持它。这是一个早期的设计决定(请参阅此处和此处)。
即使这样,今天对垂直脚本的支持还是有实际用途的。除了某些中文和日文用法外,传统的蒙古文字还需要它。该脚本在内蒙古的计算机程序中非常常用(例如example,example,example,example,example,example)。
它是从上到下写的,行从左到右环绕:
此外,表情符号和CJK字符在垂直显示时仍保持其方向(并非绝对必要,而是首选)。在下图中,顶部显示了当前的实现,底部显示了正确的垂直渲染:
// sample text
???? ????? ????? ????? ???? ???????? ??????? ?????? ???? ???? one two three four five six seven eight nine ten ?? ??? ????? English? ???????
Run Code Online (Sandbox Code Playgroud)
由于Flutter不支持垂直脚本,因此必须从头开始实施。所有实际的文本布局和绘画都是使用LibTxt在Flutter引擎中完成的,所以我无法更改它。
创建从上到下的垂直文本小部件会涉及什么?
我还在寻找答案。Rémi的答案适用于单行文本,但不适用于多行文本。
我目前正在研究三种不同的可能解决方案:
所有这些将涉及测量文本,对其进行布局并获得行列表。
我目前倾向于制作自定义的小部件和渲染对象,以模仿RichText和RenderParagraph。在后台,RenderParagraph使用TextPainter来布局和绘制文本。我现在的问题是TextPainter与底层的Skia LibTxt库紧密耦合。这就是所有实际布局和绘画的地方。除了默认的ltr和rtl外,将文本放置在其他任何地方都被证明是一个大问题。
接受的答案符合我在这个问题中提出的标准。我认为它将满足短期需求。对于应用文字样式,我有些保留,但我需要做更多测试。从长远来看,我仍然可以尝试自定义文本布局和绘画。
This solution is based on a flex-box layout. It converts the string to a list of words and puts them in vertically rotated Text widgets. These are laid out with a Wrap widget set to Axis.vertical. The Wrap widget automatically handles words that need to wrap by putting them in the next column.
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Wrap(
direction: Axis.vertical,
children: _getWords(),
),
),
);
}
List<Widget> _getWords() {
const text =
"That's all 12345 One Two Three Four Five ??????????? ???????? ????????? ???? ????? ??????";
var emoji = RegExp(r"([\u2200-\u3300]|[\uD83C-\uD83E].)");
List<Widget> res = [];
var words = text.split(" ");
for (var word in words) {
var matches = emoji.allMatches(word);
if (matches.isEmpty) {
res.add(RotatedBox(quarterTurns: 1, child: Text(word + ' ')));
} else {
var parts = word.split(emoji);
int i = 0;
for (Match m in matches) {
res.add(RotatedBox(quarterTurns: 1, child: Text(parts[i++])));
res.add(Text(m.group(0)));
}
res.add(RotatedBox(quarterTurns: 1, child: Text(parts[i] + ' ')));
}
}
return res;
}
}
Run Code Online (Sandbox Code Playgroud)
可以使用横排文本RotatedBox,这足以使文本正确包装。
Row(
children: <Widget>[
RotatedBox(
quarterTurns: 1,
child: Text(sample),
),
Expanded(child: Text(sample)),
RotatedBox(
quarterTurns: -1,
child: Text(sample),
),
],
),
Run Code Online (Sandbox Code Playgroud)
同样,Flutter现在支持文本内部的嵌入式小部件。这可用于旋转文本内的笑脸。
RotatedBox(
quarterTurns: 1,
child: RichText(
text: TextSpan(
text: 'Hello World',
style: DefaultTextStyle.of(context).style,
children: [
WidgetSpan(
child: RotatedBox(quarterTurns: -1, child: Text('')),
)
],
),
),
),
Run Code Online (Sandbox Code Playgroud)
使用起来很简单RotatedBox
RotatedBox(
quarterTurns: 1,
child: //your text
),Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1214 次 |
| 最近记录: |