0

I'm trying to create chat bubbles and have them wrap around the text without expanding to the other end of the screen. I've seen the other threads on how to do this and have tried implementing it but none of it works. Here are the threads I've seen and tried implementing the suggested fixes:

Flutter- wrapping text

Container text wrap

Wrap text in container without using a fixed width in Flutter

Currently this is what happens when I have a background in my container: Current state of my app

My code:

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
    );   

}

I've tried adding constraints on the parent container, however that requires me to create a fixed size (at least to my own understanding of flutter) and the container still starts on the left. So the messages from "Ken" would end up on the right side of the container, but the container ends in the middle of the screen.

Kupperu
  • 111
  • 2
  • 11
  • It should be, in short, Row(Expanded(Text(' ')), Container(Text('Ken'))). i.e. use an Expanded emty Text before the bubble container. – Kenneth Li Mar 14 '19 at 14:01
  • What do you mean? I've tried adding Expanded to the text section inside Expanded, and removed the expanded. Even though that briefly worked, once I removed the constraints from the parent container, everything broke. – Kupperu Mar 14 '19 at 14:20
  • no, your Expanded is inside the bubble container, I mean a Expanded EMPTY Text ouside the bubble container. – Kenneth Li Mar 14 '19 at 14:22
  • By outside the bubble container do you mean my row widget? – Kupperu Mar 14 '19 at 14:29
  • Add one more row widget – Kenneth Li Mar 15 '19 at 04:28

1 Answers1

2

You could just wrap the whole message bubble in a Row and set add a Spacer() as another child:

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

Applying that to your code, we get something like this (I also optimized some other code):

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 ]
  );
}

Also note that you shouldn't use the messaging text as a discriminating factor for replies (what if a message starts with a lowercase r...?)

Marcel
  • 8,831
  • 4
  • 39
  • 50
  • Thank you! And yes I know I shouldn't use the messaging text as a discriminating factor. This is just a temporary solution until I fully implement the backend for this app. But thanks for the help, I got it sorted! – Kupperu Mar 14 '19 at 15:29