右对齐消息时间戳与颤动消息文本字段的尾随右侧

时间:2021-02-14 23:26:37

标签: flutter layout timestamp widget messagebox

正如我在之前关于该主题的帖子 (Multi-line flutter text field occupies all of Flexible space with ugly right padding) 中提到的,我有点完美主义者。不幸的是,我的 flutter layout-fu 没有我的野心那么强大。我正在创建一个消息传递应用程序,我正在向消息框添加时间戳。到目前为止我的代码(也感谢这个答案:Complex alignment of a sub widget based on wrapping text like in the Telegram chat messenger)是这样的:

创建一行的代码:

  Widget getAppUserMessageRow() {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.center,
      mainAxisAlignment: MainAxisAlignment.end,
      children: <Widget>[
        SizedBox(width: AppState.i.chatItemUserLeftInset),
        Flexible(
          fit: FlexFit.loose,
          child: message.cm.messageType.getMessageWidget(message),
        ),
      ],
    );
  }

创建消息框本身的代码:

Widget build(BuildContext context) {
bool isFromAppUser = message.cm.isFromAppUser(AppState.i.activeUserId);

return Container(
  padding: EdgeInsets.symmetric(
    vertical: AppState.i.chatItemMessageVerticalInset),
  child:
  Container(
    decoration: BoxDecoration(
      color: isFromAppUser ? AppState.i.chatItemUserMessageBackgroundColour : Colors.white,
          //.withOpacity(!message.isFromAppUser ? 0.1 : 0.8),
      borderRadius: BorderRadius.only(
        topLeft: Radius.circular(isFromAppUser ? AppState.i.chatItemMessageBorderRadius : 0),
        topRight: Radius.circular(isFromAppUser ? 0 : AppState.i.chatItemMessageBorderRadius),
        bottomRight: Radius.circular(isFromAppUser ? AppState.i.chatItemMessageCurvedBorderRadius : AppState.i.chatItemMessageBorderRadius),
        bottomLeft: Radius.circular(isFromAppUser ? AppState.i.chatItemMessageBorderRadius : AppState.i.chatItemMessageCurvedBorderRadius),
      ),
      boxShadow: [
            BoxShadow(
              color: AppState.i.chatItemMessageBoxShadowColour,
              spreadRadius: AppState.i.chatItemMessageBoxShadowSpreadRadius,
              blurRadius: AppState.i.chatItemMessageBoxShadowBlurRadius,
              offset: AppState.i.chatItemMessageBoxShadowOffset, // changes position of shadow
            ),
          ],                
    ),
    padding: EdgeInsets.symmetric(
        vertical: AppState.i.chatItemMessageVerInset,
        horizontal: AppState.i.chatItemMessageHorInset),
    child: Stack(
      children: [
        Text(

            // WTF? This calculates enough space for the message receipt time to wrap
            message.cm.messageText + (isFromAppUser ? '              \u202F' : '        \u202F'),
            style: TextStyle(
              fontSize: AppState.i.chatItemMessageTextFontSize,
              color:
                  isFromAppUser ? AppState.i.chatItemMessageUserTextFontColour : AppState.i.chatItemMessageOtherUserTextFontColour,
            ),
            textWidthBasis: TextWidthBasis.longestLine,
          ),
          // This Positioned item creates the message timestamp in the area gained by adding the spaces above, assuming the spaces forced
          // The text field into adding an extra line.
          Positioned(
            width: 60,
            height: 15,
            right: 0,
            bottom: -2,
            child: Row(
              mainAxisSize: MainAxisSize.min,
              mainAxisAlignment: MainAxisAlignment.end,
              children: <Widget>[
                Text(
                  DateFormat.Hm().format(message.cm.messageDisplayTime(AppState.i.activeUserId)),
                  style: TextStyle(
                    fontSize: AppState.i.chatItemMessageTimeFontSize,
                    color: isFromAppUser ? AppState.i.chatItemMessageUserTimeFontColour : AppState.i.chatItemMessageOtherUserTimeFontColour,
                  ),
                  textAlign: TextAlign.right,
                ),
                !isFromAppUser ? Container() : 
                Padding(
                  padding: EdgeInsets.only(left: AppState.i.chatItemMessageReceiptLeftInset),
                  child: message.cm.getReadReceiptIcon()
                )
              ],
            ),
          ),              
      ],
    ),
  )
);

}

这里有一些好的和坏的例子 - 查看坏例子的右侧填充。时间戳应该与上面的文本更右对齐:

1

还有更多:

2

添加空格 + 一个不可打印的字符来为日期时间戳 + 阅读回执组合腾出空间是一个天才的把戏,但有一个缺点。当文本接近时间戳将占用的空间时,它会推出正确的对齐方式。因此,在上述某些情况下,盒子会占用不必要的空间。

那么,这是否可以修复,或者可以使用不同的布局来实现我正在寻找的效果?我不能使用太多计算量的东西,因为现在滚动长列表时性能相当不错。

为了让这更具体一些,一些“固定”的例子。

enter image description here enter image description here

1 个答案:

答案 0 :(得分:3)

示例:Message box with Timestamp

我觉得你可以试试这个:

  1. 计算/模拟文本并检查消息是否与时间戳重叠。
  2. 如果重叠,请添加 Math.max 以更改行。否则,返回原来的。

您需要以下东西:

  1. \n:文本小部件上方的 BoxConstraint
  2. LayoutBuilder:模拟布局(还需要TextPainterTextStyle否则可能会影响布局结果)

代码如下:

textWidthBasis

enter image description here

相关问题