知识 Flutter Flutter-VerticalText Kahvia 2022-11-19 2022-11-19 需求
今天有人问了我一个很有意思的问题:如何实现文字竖直排列,就像古诗词一样。
思路
我首先想到的是使用 Container 组件嵌套 Text 组件,固定它的宽度,这样来实现一行一个文字。看起来就像竖直排列一样。但是它的文字垂直间距很显然不方便控制。
我便去 StackOverflow 上搜索了一番 vertical text。果然有所收获。有人提出,使用 Wrap 组件去实现这个功能。分割需要竖直排列的字符串为单个字,用 Text 组件包裹每个字,然后利用 Wrap 组件的 direction 使得这些 Text 列表垂直排列,排不下则往右边另起一列。
我自然是希望古诗一列一句的。所以就不用考虑超出换列,手动分割当然最好。既然使用不到 Wrap ,用各种 ListView 来展示上面的 Text 们也是可以的。
当然了,如果是显示的宋词,那一句太长也是有可能的,为了保险起见,我还是使用了Wrap做了超出处理。
如此一来,就可以着手实现了。封装一个用 Wrap 为核心的自定义组件,主要用于展示古诗的一句。我们拿到一个古诗后,可以将古诗按标点符号分割,分割后的句子用自定义的 VerticalText 显示就可以了。我更倾向于用 Row 组件去显示,因为我能用它决定主轴方向和交叉轴方向的起点,这能做到古诗句的上对齐,和右对齐。用 ListView 的话,可以很方便地翻转古诗句的顺序,但是不太方便对齐。
具体的实现可以参考如下代码。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 import 'package:flutter/material.dart' ;class MyPage extends StatelessWidget { const MyPage({super .key}); @override Widget build(BuildContext context) { List <VerticalText> poetry=const [ VerticalText("将进酒," ), VerticalText("杯莫停。" ), VerticalText("与君歌一曲," ), VerticalText("请君为我倾耳听。" ) ]; return Scaffold( appBar: AppBar( title: const Text("test" ), ), body: Center( child: Row( mainAxisAlignment: MainAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.start, children: List .from(poetry.reversed) , ), ), ); } } class VerticalText extends StatelessWidget { final String text; const VerticalText(this .text,{Key? key}) : super (key: key); @override Widget build(BuildContext context) { List <Text> texts=text.split("" ).map((string) => Text(string, style: const TextStyle(fontSize: 17 ))).toList(); return Padding( padding: const EdgeInsets.symmetric(horizontal: 10 ), child: Wrap( direction: Axis.vertical, spacing: 20 , runSpacing: 30 , alignment: WrapAlignment.center, children: texts, ), ); } }