TextDirection文档说:
Flutter旨在满足编写的应用程序的需求 世界上任何一种当前使用的语言,无论它们是否使用 从右到左或从左到右的书写方向。 颤振不 支持其他书写模式,例如竖排文字或自画像 文字,因为这些文字很少在计算机程序中使用。 (添加了重点)
Flutter不仅不支持垂直文本,将来也不会正式支持它。这是一个早期的设计决策(请参见here和here)。
即使如此,今天对垂直脚本的支持还是有实际用途的。除了某些Chinese and Japanese用途之外,traditional Mongolian script还需要它。内蒙古的计算机程序(example,example,example,example,example,example中非常常用的脚本。
它是从上到下写的,行从左到右环绕:
此外,表情符号和CJK字符在垂直显示时仍保持其方向(并非绝对必要,而是首选)。在下图中,顶部显示了当前的实现,底部显示了正确的垂直渲染:
// sample text
ᠨᠢᠭᠡ ᠬᠣᠶᠠᠷ ᠭᠣᠷᠪᠠ ᠳᠥᠷᠪᠡ ᠲᠠᠪᠤ ᠵᠢᠷᠭᠤᠭᠠ ᠳᠣᠯᠣᠭᠠ ᠨᠠᠢᠮᠠ ᠶᠢᠰᠦ ᠠᠷᠪᠠ one two three four five six seven eight nine ten ??汉字 한국어 モンゴル語 English? ᠮᠣᠩᠭᠣᠯ︖
由于Flutter不支持垂直脚本,因此必须从头开始实施。所有实际的文本布局和绘画都是在LibTxt的Flutter引擎中完成的,因此无法更改。
创建顶部到底部垂直文本小部件会涉及什么?
我还在寻找答案。 Rémi的答案适用于单行文本,但不适用于多行文本。
我目前正在研究三种可能的解决方案:
所有这些都涉及测量文本,对其进行布局并获得行列表。
我目前倾向于制作自定义窗口小部件和渲染对象,以模仿RichText和RenderParagraph。在后台,RenderParagraph使用TextPainter来布局和绘制文本。我现在的问题是TextPainter与底层的Skia LibTxt库紧密耦合。这就是所有实际布局和绘画的地方。在默认的ltr和rtl之外的其他任何地方放置文本都被证明是一个大问题。
接受的答案符合我在此问题中提出的标准。我认为它将满足短期需求。对于应用文字样式,我有些保留,但我需要做更多测试。从长远来看,我仍然可以尝试自定义文本布局和绘画。
答案 0 :(得分:6)
可以使用RotatedBox
生成Sideway文本,这足以使文本正确包装。
Row(
children: <Widget>[
RotatedBox(
quarterTurns: 1,
child: Text(sample),
),
Expanded(child: Text(sample)),
RotatedBox(
quarterTurns: -1,
child: Text(sample),
),
],
),
类似地,Flutter现在支持文本内部的嵌入式小部件。这可以用于旋转文本内的笑脸。
RotatedBox(
quarterTurns: 1,
child: RichText(
text: TextSpan(
text: 'Hello World',
style: DefaultTextStyle.of(context).style,
children: [
WidgetSpan(
child: RotatedBox(quarterTurns: -1, child: Text('?')),
)
],
),
),
),
答案 1 :(得分:6)
此解决方案基于弹性盒布局。它将字符串转换为单词列表,并将其放入垂直旋转的Text小部件中。使用Wrap
小部件设置为Axis.vertical
进行布局。 “包装”小部件将需要包装的单词放在下一列中,从而自动处理这些单词。
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;
}
}
答案 2 :(得分:2)
如果您制作的自定义字体的所有符号都旋转了180°(硬部分),则可以将 textDirection 更改为 TextDirection.rtl (从右到左) ),然后将文本旋转四分之一(这也不容易)。
答案 3 :(得分:2)
使用很简单RotatedBox
RotatedBox(
quarterTurns: 1,
child: //your text
),
答案 4 :(得分:0)
简单绘制所需内容
示例flutter-widget-positioning-guide
然后
Column(
children: [
MyWidget(),
MyWidget(),
MyWidget()
]
);
// or swap a Column for a Row to flip the axis
Row(children: [ ]);
// and this is all just sugar for the Flex widget
Flex(
direction: Axis.vertical<--------------
)
答案 5 :(得分:0)
我最终创建了一个自定义小部件来处理文本呈现。在撰写本文时,它不能正确旋转表情符号和CJK字符,但可以处理方向和换行符。
这不是一件容易的事,但它很灵活。如果其他答案不能满足您的需求,则该问题的其他访问者也可以遵循类似的模式。
如果您想进一步控制Flutter中的文本呈现,请阅读My First Disappointment with Flutter并在this GitHub issue上添加注释。