flutterwidgetword-wrapmultilinehorizontal-line

Multi-line flutter text field occupies all of Flexible space with ugly right padding


I'm building chat bubbles in a flutter app and it's triggered my inner perfectionist. The main code for displaying an incoming message from another chat user is:

  Widget getOtherUserMessageRow() {
    return Row(
      crossAxisAlignment: CrossAxisAlignment.center,
      mainAxisAlignment: MainAxisAlignment.start,
      children: <Widget>[
        message.cm.senderIsSameAsPreviousOnSameDay(AppState.i.activeUserId)
          ? SizedBox(width: AppState.i.chatItemOtherUserLeftInset)  // If sender is previous message sender on same day, don't repeat avatar
          : message.getCreatorAvatar(),
        SizedBox(width: AppState.i.chatItemOtherUserAvatarRightPadding),  // Leave fixed gap for other messages
        Flexible(
          fit: FlexFit.loose,
          child: message.cm.messageType.getMessageWidget(message),
        ),
        SizedBox(width: AppState.i.chatItemOtherUserMessageRightPadding),  // Fixed gap for non-user messages
      ],
    );
  }

Then we have the code that creates the bubble, indirectly called via 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,
          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: Text(
                message.cm.messageText,
                style: TextStyle(
                  fontSize: AppState.i.chatItemMessageTextFontSize,
                  color:
                      isFromAppUser ? AppState.i.chatItemMessageUserTextFontColour : AppState.i.chatItemMessageOtherUserTextFontColour,
                )
              ),
        ),
    );
  }

So what I get is this...

Single line - works fine doesn't use all horizontal space.

Multi-line - uses all available horizontal space up to the sized box on the right with ugly right-hand-side wrapping:

Multi-line another (bad) example:

3

So what I really want is this:

enter image description here

Any ideas? I'm kinda thinking it's not possible because the TextField would have to intelligently adjust the horizontal fit based on it's internal wrapping. But I'm willing to be proven otherwise by you layout gurus :-)


Solution

  • Are you looking for Paragraph.longestLine property?

    Text(
      textWidthBasis: TextWidthBasis.longestLine,
      ...
    )