0

I have a function that returns a list of Widget like this:

buildCaption() {
  List<String> splittedCaption = caption.split(' ');
  List<Widget> mergedCaption = new List<Widget>();
  for (String captionSplit in splittedCaption) {
    print(captionSplit);
    if (captionSplit.contains('#')) {
      mergedCaption.add(Text(
        '$captionSplit ',
        style: TextStyle(color: Colors.blue)
      ));
    } else {
      mergedCaption.add(Text('$captionSplit '));
    }
  }
  return mergedCaption;
}

Then, I have a Row Widget that looks like this:

Row(
  crossAxisAlignment: CrossAxisAlignment.start,
  children: <Widget>[
    Expanded(child: Row(children: buildCaption())
  ]
)

However, the Expanded doesn't prevent the row from overflowing the screen size. Please how do I display the List of Widgets returned from the buildCaption method while still preventing it from overflowing the screen size?

Whole code:

buildPostFooter() {
  return Column(
    children: <Widget>[
      mediaUrl.length > 1 ? Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: map<Widget>(
          mediaUrl,
          (index, media) {
            return Container(
              width: 8.0,
              height: 8.0,
              margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 2.0),
              decoration: BoxDecoration(
                shape: BoxShape.circle,
                color: currentMedia == index
                  ? Theme.of(context).primaryColor
                  : Color.fromRGBO(0, 0, 0, 0.4)
              )
            );
          }
        )
      ) : Text(''),
      Row(
        mainAxisAlignment: MainAxisAlignment.start,
        children: <Widget>[
          Padding(padding: EdgeInsets.only(top: 40.0, left: 15.0)),
          GestureDetector(
            onTap: handleLikePost,
            child: Icon(
              isLiked ? Icons.favorite : Icons.favorite_border,
              size: 28.0,
              color: Colors.pink
            )
          ),
          Padding(padding: EdgeInsets.only(right: 5.0)),
          Text(
            '$likeCount likes',
            style: TextStyle(
              color: Colors.black,
              fontWeight: FontWeight.bold
            )
          ),
          Padding(padding: EdgeInsets.only(right: 20.0)),
          GestureDetector(
            onTap: () => showComments(
              context,
              postId: postId,
              ownerId: ownerId,
              mediaUrl: mediaUrl
            ),
            child: Icon(
              Icons.chat,
              size: 28.0,
              color: Colors.blue[900]
            )
          ),
          Padding(padding: EdgeInsets.only(right: 5.0)),
          Text(
            '$commentCount comments',
            style: TextStyle(
              color: Colors.black,
              fontWeight: FontWeight.bold
            )
          )
        ],
      ),
      Padding(
        padding: EdgeInsets.only(
          top: mediaUrl.length > 0 && caption.isNotEmpty ? 10.0 : 0.0
        )
      ),
      mediaUrl.length > 0 && caption.isNotEmpty ? Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Container(
            margin: EdgeInsets.only(left: 20.0),
            child: Text(
              '$username ',
              style: TextStyle(
                color: Colors.black,
                fontWeight: FontWeight.bold
              )
            )
          ),
          Expanded(child: Row(children: buildCaption()))
        ],
      ) : timeWidget(),
      mediaUrl.length > 0 && caption.isNotEmpty ? timeWidget() : Text('')
    ],
  );
}
3
  • Try to wrap each child text in an Expanded. Don't wrap the Row in an Expanded. Commented Feb 5, 2020 at 6:26
  • @Smashing That throws an error: Unhandled Exception: Cannot hit test a render box with no size. Commented Feb 5, 2020 at 6:36
  • Wrapping second Row in Expanded is necessary because it tells the second Row how big it should be drawn because it is inside a Row Commented Feb 5, 2020 at 6:37

4 Answers 4

1
        Row(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Expanded(
              child: RichText(
                text: TextSpan(
                  children: caption.split(' ').map(
                    (item) {
                      if (item.contains('#')) {
                        return TextSpan(
                          text: '$item ',
                          recognizer: new TapGestureRecognizer()
                            ..onTap = () => print('hashtag$item'),
                          style: TextStyle(color: Colors.blue),
                        );
                      } else if (item.contains('.')) {
                        return TextSpan(
                          text: '$item ',
                          recognizer: new TapGestureRecognizer()
                            ..onTap = () => print('https://www.$item'),
                          style: TextStyle(color: Colors.blue),
                        );
                      } else {
                        return TextSpan(
                          text: '$item ',
                        );
                      }
                    },
                  ).toList(),
                ),
              ),
            )
          ]
        )
Sign up to request clarification or add additional context in comments.

8 Comments

That didn't work either. It removed the overflow error but it made the text look weird
It happened because all the Text Widgets are constrained by the second Row width.
I removed the second row, used only one row (wrapped in expanded), with each child text wrapped in expanded and the text still looks weird. Here is an image so you can see for yourself: imgur.com/a/VgtJ8US how to fix that?
Can you look at the whole code i just added to the question to see how the structure looks like, if I remove the second row, how do I call buildCaption()?
First off, what do you want to achieve because you only asked how to prevent overflowing screen size. After looking at the image, I think your approach is wrong using "List" of Text Widget
|
1

you can`t use row for multiple text widget and expect line breaks

you should use Rich Text for multiple style in one text

try below code:

  buildCaption() {
    List<String> splittedCaption = caption.split(' ');
    List<TextSpan> mergedCaption = List<TextSpan>();
    for (String captionSplit in splittedCaption) {
      print(captionSplit);
      if (captionSplit.contains('#')) {
        mergedCaption.add(TextSpan(
            text: '$captionSplit ',
            style: TextStyle(color: Colors.blue)
        ));
      } else {
        mergedCaption.add(TextSpan(text: '$captionSplit '));
      }
    }
    return mergedCaption;
  }

 

Row(
  crossAxisAlignment: CrossAxisAlignment.start,
  children: <Widget>[
    Expanded(
      child: RichText(
      text: new TextSpan(
        style: new TextStyle(
          fontSize: 14.0,
          color: Colors.black,
        ),
        children: buildCaption(),
      ),
    ))
  ]
)

Comments

0

Try using SingleChildScrollView instead of Expanded

Comments

0

I dont know what you are trying to do, but here you have a horizontal scrollable list. If you want to use row I will suggest using the Wrap. widget.

final List<Widget> widgetList = buildCaption();

    @override
    Widget build(BuildContext context) {
        return ListView.builder(
                  scrollDirection: Axis.horizontal,
                  padding: const EdgeInsets.all(8),
                  itemCount: widgetList.length,
                  itemBuilder: (BuildContext context, int index) {
                     return index;
                  }
               );
    }
  1. suggestion: Regarding the overflow you can use a Container instead of Expanded, and set width: MediaQuery.of(context).size.width*0.5 on the Container, this is eqvivalent to 50% of screen width.

  2. suggestion: You can use Grid-list and set crossAxisCount: widgetList().length if you want everything to be in one line, se example here:

https://flutter.dev/docs/cookbook/lists/grid-lists

1 Comment

Please look at the full code i posted. Basically, I have a list of text widgets inside a row but they are overflowing the screen, and i am trying to get them to have an automatic line break instead of overflowing the screen

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.