4
votes

I try to build a Chat-App where the "New Message"-Screen contains of the receipient and the message. I want that the TextField fills up the remaining space on the screen. Like a Textarea in HTML.

  1. I have tried to increase the maxLines to a big number which caused an Pixel overflow error with the Floating Action Button.
  2. I tried wrapping it in a Expanded Widget which had no effect on it.

This is my current Structure of the Layout:

    body: new Column(
        children: <Widget>[
          new ListTile(
            dense: false,
            title: new Text("Alex XYZ",
                //...
          ),
          Divider(),
          new TextField(
              decoration: InputDecoration(hintText: "Insert your message",),
              scrollPadding: EdgeInsets.all(20.0),
              autofocus: true,
          )
        ],
      ),

With the TextField in the Code above I can not even write multiple lines. If I add maxLines: 2 I can press enter to move down, but this does not look clean and you can not scroll in that area.

I hope somebody can help me on how to expand that to the whole screen.

Best Regards Alex!

3
try replacing Column widget With ListView widget - Vicky Salunkhe

3 Answers

3
votes

For now you can use maxline 99999 because there is already open issue in flutter if we pass double.infinity.toInt() in maxline for unlimited lines.

So to create multiline textview with scroll functionality you can use maxline 99999 with SingleChildScrollView widget as below. It will allow you to scroll as well maxline.

Also it will fit in the screen if you used as below example:

return Scaffold(
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(widget.title),
      ),
      body: Center(
        child: SingleChildScrollView(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              TextField(
                decoration: InputDecoration(hintText: "Insert your message",),
                scrollPadding: EdgeInsets.all(20.0),
                keyboardType: TextInputType.multiline,
                maxLines: 99999,
                autofocus: true,)
            ],
          ),
        ),
      ),
      resizeToAvoidBottomPadding: true,
    );
2
votes

Anyone who's reading this in Jan 2021 and henceforth...

Expanded() widget is what will help you

Just wrap your TextField() with Expanded() like this...

Expanded(
    child: TextField(
              decoration: InputDecoration(hintText: "Insert your message",),
              scrollPadding: EdgeInsets.all(20.0),
              autofocus: true,
          )
)

This will take the remaining screen into account and treat like a giant TextField()

Also, if you want to remove the TextField's underline, which I guess is necessary for apps like this, use collapsed() constructor of InputDecoration class, like this

InputDecoration.collapsed()

NB: I wanted add this as a comment to the original question, but due to lower reputation unable to do so.

0
votes

You can use the below function , what it will do is , it will initially show you a textfield with 6 lines then as the user enters new content max lines can go upto infinity.

Widget _postBodyTextField(){ return LayoutBuilder(
builder: (context, size){
  TextSpan text = new TextSpan(
    text: editTextController.text,
  );

  TextPainter tp = new TextPainter(
      text: text,
      textDirection: TextDirection.ltr,
      textAlign: TextAlign.left,
  );
  tp.layout(maxWidth: size.maxWidth);

  int lines = (tp.size.height / tp.preferredLineHeight).ceil();
  int maxLines = 6;

  return TextField(
    controller: editTextController,
    maxLines: lines > maxLines ? null : maxLines,
    textInputAction: TextInputAction.newline,
     decoration: InputDecoration(
              hintText: "Start Writing here..."
            ),
  );}); }