我的目标是重现 Telegram(以及其他一些聊天应用程序)用于聊天消息气泡的复杂布局。气泡并不复杂,但事实证明,让气泡中的文本与日期很好地对齐却异常复杂:
类似的帖子已经在这里发布和回答,但关键的是它不能正确处理文本换行(下面详细介绍的情况#1和#2),因为填充右侧保持不变,浪费了大量的屏幕空间,而且看起来很糟糕。(如果还不清楚,请参见此处:2)。
我已经编译了我认为的 3 个“用例”来重现上图中的布局:
情况 #1:是迄今为止最复杂的,它似乎是日期小部件的一个小容器,占用了最少的空间,可能是 mainAxisSize 设置为 min 的一行。复杂的部分在于如何允许文本在上方和旁边流动,同时自然换行以避免任何重叠。
情况#2:如果上面的#1 重叠,由于文本行的字符数量几乎完美(以便不会自然换行),它将转换到下面的情况#2 中看到的布局,这似乎是一个具有两个嵌套行的列。
情况#3:这是迄今为止最容易单独实现的,并且可以通过多种方式完成,最简单的是带有两个文本小部件的单行。我相当确定,如果解决方案能够实现上述#1 和#2,那么这个解决方案应该是免费的。
我尝试过的:
将两者堆叠起来,将日期包裹在 aPositioned之类的东西中bottom: 0, right: 15。如果您添加至少 25 的 padding-right,这基本上只能实现情况 #1。
我还尝试过 RichText,它是迄今为止最有前途的,它可以处理所有情况,但远没有 telegram 所做的那么优雅。这样做的主要缺点是我仍然需要使用某种堆栈来放置“已发送和已查看”图标复选标记,因为图标不能包含在 RickText 跨度中......所以我仍然需要一些向右填充 + 底部填充,这样它们就不会重叠。这是该代码和下面的图片:
RichText(
text: TextSpan(
text: _message.textContent,
style: DefaultTextStyle.of(context).style.merge(TextStyle(fontSize: 16)),
children: <TextSpan>[
TextSpan(text: ' ' + DateFormat('H:mm a').format(_message.createdDate.toLocal()).toString(),
style: Theme.of(context).textTheme.caption.merge(
TextStyle(
fontSize: 10,
)
),
),
],
),
),
Run Code Online (Sandbox Code Playgroud)
理想情况下,日期将是一个单独的小部件,并且两者将与 spaceBetween 灵活对齐,因此日期始终保持在右下角,如上面的电报图像所示。哦,我正在使用该bubble: ^1.1.9+1小部件来显示实际的聊天气泡。
找到了解决方案,并对其如此简单的感觉感到非常愚蠢,但不能抱怨,因为它完美地工作:
\n\nText(\n _message.textContent + \' \xe2\x80\xaf\',\n style: DefaultTextStyle.of(context).style.merge(TextStyle(fontSize: 16)),\n),\nRun Code Online (Sandbox Code Playgroud)\n\n这里的“魔力”是通过在消息末尾添加 30 个左右的空格,您可以为换行文本小部件的底行提供完美的填充量。无需复杂或昂贵的重新绘制或布局逻辑。
\n\n确保在空格字符串的末尾放置一个非打印字符,否则 FluttertrimRight()默认情况下会在您的文本小部件上执行某种操作,但它将无法工作。我使用了U+202F,如果你从这里复制代码(StackOverflow 不会自动删除这些字符,它应该可以工作)。
将上面的文本小部件放入堆栈中,并将日期/图标放置在右下角,如下所示:
\n\nPositioned(\n width: 60,\n height: 9,\n right: 0,\n bottom: 0,\n child: Row(\n mainAxisSize: MainAxisSize.min,\n mainAxisAlignment: MainAxisAlignment.end,\n children: <Widget>[\n Text(\n DateFormat(\'H:mm a\').format(_message.createdDate.toLocal()).toString(),\n style: Theme.of(context).textTheme.caption.merge(TextStyle(fontSize: 10)),\n textAlign: TextAlign.right,\n ),\n Padding(\n padding: const EdgeInsets.only(left: 4.0),\n child: Icon(Icons.done_all, size: 13),\n )\n ],\n ),\n),\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
589 次 |
| 最近记录: |