将容器包装在文本周围,以防止聊天

时间:2019-03-14 13:46:15

标签: flutter

我正在尝试创建聊天气泡,并让它们环绕文本而不会扩展到屏幕的另一端。我已经看到了其他有关如何执行此操作的线程,并尝试实现它,但没有一个起作用。这是我见过并尝试实施建议的修复程序的线程:

Flutter- wrapping text

Container text wrap

Wrap text in container without using a fixed width in Flutter

当前,当我的容器中有背景时会发生以下情况: Current state of my app

我的代码:

Widget build(BuildContext context) {
return new SizeTransition(
    sizeFactor: new CurvedAnimation(
        parent: animationController.view,
        curve: Curves.easeOut),
    axisAlignment: 0.0, 
    child: new Container(
        decoration: BoxDecoration(
          border: Border.all(
            color: (text[0]=='r') ? lightVioletBlue :mintgreen,
            width: 2.0,
            style: BorderStyle.solid,
          ),
          borderRadius:  BorderRadius.all(Radius.circular(20)),
          color: (text[0] == 'r') ? lightVioletBlue:mintgreen,
        ),
        margin: const EdgeInsets.symmetric(vertical: 10.0),
        child: new Row(           
          mainAxisSize: MainAxisSize.min,            
          children: <Widget>[
            new Container(
              margin: const EdgeInsets.only(right: 16.0),
              child: (text[0] == 'r') //If first letter is an r, then it indicates it's a reply.
                  ? new CircleAvatar(child: new Text(_otherName[0]))
                  : null
            ),
            new Expanded(
              child: new Column(
                  crossAxisAlignment: (text[0] == 'r') //If first letter is an r, then it indicates it's a reply.
                      ? CrossAxisAlignment.start
                      : CrossAxisAlignment.end,
                  children: <Widget>[
                    new Text((text[0] == 'r') ? _otherName : _name, //If first letter is an r, then it indicates it's a reply.
                        style: (text[0] == 'r') ? TextStyle(color: Colors.white) : Theme.of(context).textTheme.subhead),
                    new Container(
                      margin: const EdgeInsets.only(top: 5.0),
                      child: (text[0] == 'r') //If first letter is an r, then it indicates it's a reply.
                          ? new Text(text.substring(1), style: TextStyle(color: Colors.white))
                          : new Text(text),
                    ),
                  ],
                ),                 
            ),
            new Container(
                margin: const EdgeInsets.only(left: 16.0),
                child: (text[0] == 'r') //If first letter is an r, then it indicates it's a reply.
                    ? null
                    : new CircleAvatar(child: new Text(_name[0]))),
            ],
          ),
        ) //new
    );   

}

我尝试在父容器上添加约束,但是这要求我创建固定大小(至少从我自己对flutter的理解),并且该容器仍从左侧开始。因此,来自“肯”的消息将最终显示在容器的右侧,但容器将在屏幕中间结束。

1 个答案:

答案 0 :(得分:0)

您可以将整个消息气泡包装在Row中,并设置将Spacer()添加为另一个孩子:

Row(
  children: <Widget>[ messageBubble, Spacer() ]
),

将其应用到您的代码中,我们将得到如下信息(我还优化了其他一些代码):

Widget build(BuildContext context) {
  bool isReply = (text[0] == r);
  String name = isReply ? _otherName : name;

  Widget profilePicture = Container(
    padding: const EdgeInsets.symmetric(horizontal: 16),
    child: CircleAvatar(child: Text(name[0]))
  );

  Widget messageText = Column(
    crossAxisAlignment: isReply ? CrossAxisAlignment.start : CrossAxisAlignment.end,
    children: <Widget>[
      Text(name,
        style: isReply
          ? TextStyle(color: Colors.white)
          : Theme.of(context).textTheme.subhead
      ),
      SizedBox(height: 5),
      isReply ? Text(text.substring(1), style: TextStyle(color: Colors.white))
        : Text(text),
    ],
  );

  Widget messageBubble = SizeTransition(
    sizeFactor: CurvedAnimation(
      parent: animationController.view,
      curve: Curves.easeOut
    ),
    axisAlignment: 0, 
    child: Container(
      decoration: BoxDecoration(
        border: Border.all(
          color: isReply ? lightVioletBlue : mintgreen,
          width: 2,
          style: BorderStyle.solid,
        ),
        borderRadius: BorderRadius.circular(20),
        color: isReply ? lightVioletBlue : mintgreen,
      ),
      margin: const EdgeInsets.symmetric(vertical: 10),
      child: Row(
        mainAxisSize: MainAxisSize.min,            
        children: isReply
          ? <Widget>[ profilePicture, messageText ]
          : <Widget>[ messageText, profilePicture ],
      ),
    ),
  );

  return Row(
    children: isReply
      ? <Widget>[ messageBubble, Spacer(), ]
      : <Widget>[ Spacer(), messageBubble ]
  );
}

还请注意,您不应将消息文本用作回复的区分因素(如果消息以小写r ...开头)。