How can I put a widget after Exapnded Long Text in Row?

1.7k Views Asked by At

How can I a dynamic long text with another widget (like a button) Expanded in a row like this:

enter image description here


I try Expanded, Flexible and Warp and I did not reach a conclusion.

! attention to I doesn't want this to be in a Stack or use Padding from the bottom! cause this text to have will change and its length may be bigger or shorter.


UPDATE : I try to use ExtendedText, but the child of TextOverFlowWidget doesn't show for me. my code:

Container(
  color: Colors.amber,
  height: 70,
  child: ExtendedText(
    'bbbbb ${toPhoneStyle(widget.inputPhone)}  (${widget.selectedCountry.dialCode})  aaaaaa aaaaaaaaaaa',
     overflowWidget: TextOverflowWidget(
        // maxHeight: double.infinity,
        // align: TextOverflowAlign.right,
        // fixedOffset: Offset.zero,
        child: Container(
            width: 60,
            height: 60,
            color: Colors.red,
            ),
         ),
      ),
   ),

But if miniaturize height of Container like height:20 , show like this:

3

There are 3 best solutions below

1
On BEST ANSWER

Try this: Extended text package

There is an overflow widget you can use.

Check their example:

ExtendedText(...
        overFlowWidget:
            TextOverflowWidget(
                //maxHeight: double.infinity,
                //align: TextOverflowAlign.right,
                //fixedOffset: Offset.zero,
                child: Row(
                  mainAxisSize: MainAxisSize.min,
                  children: <Widget>[
                    const Text('\u2026 '),
                    RaisedButton(
                      child: const Text('more'),
                      onPressed: () {
                        launch(
                            'https://github.com/fluttercandies/extended_text');
                      },
                    )
                  ],
                ),
              ),
        ...
      )

Ok turned out that you need to specify maxLines for overflow to work properly. I think you are instead going for a widget that follows the text. You can try Text.rich() widget

Text.rich(
  TextSpan(
    text: 'This is an example text!',
    children: [
      WidgetSpan(
        // Set the alignment
        alignment: PlaceholderAlignment.middle,
        // You can put any widget inline with text using WidgetSpan
        child: Container(
          margin: const EdgeInsets.only(left: 8.0),
          child: ElevatedButton(
            child: Text("Read more..."),
            onPressed: () {},
          ),
        ),
      ),
    ],
  ),
);

You don't need the extended text package in this case.

0
On

Apparently, you can use the RichText widget to wrap text and widgets in a line i.e. it is meant to display text using multiple display styles. The text is rendered using the children of type <TextSpan> or <WidgetSpan>.

The following code will explain the exact thing you were trying in your question. Please note that I have only used a stateful widget because I was working with something else too, so I just edited everything in that widget only, you can use a stateless widget if you do not plan to introduce any state here.

Full Code:

import 'package:flutter/material.dart';

void main()
{
  runApp(MaterialApp(
    home: Home(),
  ));
}

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  final String str = 'Some really long text to show the working of a wrap widget'
      + ' and place a button at the end of the text and it will then prove that'
      + ' you can do the same with other kind of widgets.';
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Center(
          child: Container(
            width: (MediaQuery.of(context).size.width) / 1.3,
            decoration: BoxDecoration(
              color: Colors.orange[100],
            ),
            child: RichText(
              text: TextSpan(
                children: [
                  TextSpan(
                    text: str,
                    style: TextStyle(
                      fontSize: 24,
                      color: Colors.black,
                    ),
                  ),
                  // treat the child of WidgetSpan as the parameter to insert
                  // whatever widget you wish to put here
                  // SizedBox is only used to put a little space after the text string
                  WidgetSpan(
                    child: SizedBox(width: 5,),
                  ),
                  WidgetSpan(
                    child: Container(
                      child: RaisedButton(
                        color: Colors.blueAccent,
                        onPressed: (){},
                        child: Text('Button'),
                      ),
                    ),
                  ),
                ]
              ),
            ),
          ),
        ),
      ),
    );
  }
}

Result after rendering:

Displaying a widget in the same line where a text string ends

0
On

Here is a full example.

class TestWidget extends StatefulWidget {
  const TestWidget({
    super.key,
  });

  @override
  State<TestWidget> createState() => _TestWidgetState();
}

class _TestWidgetState extends State<TestWidget> {

  bool showMoreInfo = false;
  void onTap(){
    setState(() {
      showMoreInfo = !showMoreInfo;
    });
  }

  String removeLastWord(String input) {
    if (input.isEmpty || input.endsWith(' ') || input.endsWith('.')) {
      return input;
    } else {
      int lastSpaceIndex = input.lastIndexOf(' ');
      if (lastSpaceIndex == -1) {
        return '';
      } else {
        return input.substring(0, lastSpaceIndex);
      }
    }
  }

  final content = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum";
  final maxLengthLimit = 160;

  @override
  Widget build(BuildContext context) {
    final bool isBigText = content.length>maxLengthLimit;
    final maxLength = content.length<maxLengthLimit? content.length : maxLengthLimit;
    String finalText = showMoreInfo
        ? content
        : isBigText? removeLastWord(content.substring(0, maxLength)) : content;

    return InkWell(
      onTap: onTap,
      child: Text.rich(
        style: TextStyle(
            fontSize: 14,
            color: Colors.white.withOpacity(0.8)),
        softWrap: true,
        textAlign: TextAlign.center,
        TextSpan(
          children: [
            TextSpan(
              text: finalText,
            ),
            if(isBigText)
              WidgetSpan(
                  child: Padding(
                    padding: const EdgeInsets.only(left: 5.0),
                    child: Container(
                      width: 20,
                      height: 20,
                      decoration: BoxDecoration(
                          borderRadius: BorderRadius.circular(7),
                          border: Border.all(
                              width: 1, color: Colors.white.withOpacity(0.2))),
                      child: Icon(
                        showMoreInfo
                            ? Icons.keyboard_arrow_up
                            : Icons.more_horiz,
                        size: 11,
                        color: Colors.white,
                      ),
                    ),
                  )),
          ],
        ),
      ),
    );
  }
}

enter image description here

enter image description here