title: Minlines or similar in TextField Flutter
body: <pre><code>import 'package:flutter/foundation.dart';
  import 'package:flutter/material.dart';
  import 'package:flutter/services.dart';
  
  class Todo {
    String title;
    String description;
  
    Todo(this.title, this.description);
  }
  
  class TextEditingControllerWorkaroud extends TextEditingController {
    TextEditingControllerWorkaroud({String text}) : super(text: text);
    void setTextAndPosition(String newText, int caretPosition) {
      int offset = caretPosition != null ? caretPosition : newText.length;
      value = value.copyWith(
          text: newText,
          selection: TextSelection.collapsed(offset: offset),
          composing: TextRange.empty);
    }
  }
  
  void main() {
    runApp(MaterialApp(
      title: 'Passing Data',
      home: TodosScreen(
        todos: List.generate(
          20,
          (i) =&gt; Todo(
                'Todo $i',
                'A description of what needs to be done for Todo $i',
              ),
        ),
      ),
    ));
  }
  
  class TodosScreen extends StatelessWidget {
    final List&lt;Todo&gt; todos;
  
    TodosScreen({Key key, @required this.todos}) : super(key: key);
  
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(
          title: Text('Todos'),
        ),
        body: ListView.builder(
          itemCount: todos.length,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text(todos[index].title),
              onTap: () async {
                Map results = await Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) =&gt; DetailScreen1(todo: todos[index]),
                  ),
                );
                if (results["new"]!=results["old"] || results["newTitle"]!=results["oldTitle"]){
                    todos[index].description = results["new"];
                    todos[index].title = results["oldTitle"];
                    final snackBar = SnackBar(duration: Duration(milliseconds: 2000),
                        content: Text('Todo Saved Succesfully'),
                        action: SnackBarAction(
                            label: 'Undo',
                            onPressed: () {
                                print("go back to old");
                                todos[index].description = results["old"];
                                todos[index].title = results["oldTitle"];
                            },
                        ),
                    );
  
                    // Find the Scaffold in the Widget tree and use it to show a SnackBar!
                    Scaffold.of(context).hideCurrentSnackBar();
                    Scaffold.of(context).showSnackBar(snackBar);
                }
  
              },
            );
          },
        ),
      );
    }
  }
  
  class DetailScreen1 extends StatefulWidget {
    final Todo todo;
  
    DetailScreen1({Key key, @required this.todo}) : super(key: key);
  
    @override
    DetailScreen1State createState() =&gt; DetailScreen1State();
  }
  
  class DetailScreen1State extends State&lt;DetailScreen1&gt; {
    var descriptionTextContent = "";
    var titleTextContent = "";
  
    @override
    void initState() {
      super.initState();
      print("intialized");
      descriptionTextContent = widget.todo.description;
      titleTextContent = widget.todo.title;
    }
  
    @override
    Widget build(BuildContext context) {
  
      TextEditingControllerWorkaroud descriptionEditWidgetController =
          TextEditingControllerWorkaroud(text: descriptionTextContent);
      TextEditingControllerWorkaroud titleEditWidgetController =
      TextEditingControllerWorkaroud(text: titleTextContent);
  
      TextField descriptionEditWidget = new TextField(
        maxLines: 4,
        keyboardType: TextInputType.multiline,
        controller: descriptionEditWidgetController,
        onChanged: (value) {
          handleCurrentText(value, descriptionEditWidgetController);
        },
      );
      TextField titleEditWidget = new TextField(
        maxLines: 1,
        keyboardType: TextInputType.text,
        controller: titleEditWidgetController,
        onChanged: (value) {
          handleCurrentTitle(value, titleEditWidgetController);
        },
      );
      descriptionEditWidgetController.setTextAndPosition(
          descriptionTextContent, descriptionTextContent.length);
      titleEditWidgetController.setTextAndPosition(
          titleTextContent, titleTextContent.length);
  
  
  
      return WillPopScope(
        child: Scaffold(
          appBar: AppBar(
            title: Text(widget.todo.title),
            leading: new IconButton(
                icon: new Icon(Icons.arrow_back),
                onPressed: () {
                    SystemChannels.textInput.invokeMethod('TextInput.hide');
                    Navigator.pop(context, {
                      'new': descriptionTextContent,
                      "old": widget.todo.description,
                      "newTitle": titleTextContent,
                      "oldTitle": widget.todo.title,
                    },
                    );
                },
            ),
          ),
          body: Padding(
              padding: EdgeInsets.all(16.0), child: Column(children: &lt;Widget&gt;[titleEditWidget, descriptionEditWidget],)),
        ),
        onWillPop: () {
          Navigator.pop(context, {
            'new': descriptionTextContent,
            "old": widget.todo.description,
            "newTitle": titleTextContent,
            "oldTitle": widget.todo.title,
          },
          );
        },
      );
    }
  
    handleCurrentText(String value,
        TextEditingControllerWorkaroud descriptionEditWidgetController) {
      setState(() {
        descriptionTextContent = value;
        print("value is " + value);
      });
    }
  
    void handleCurrentTitle(String value, TextEditingControllerWorkaroud titleEditWidgetController) {
      setState(() {
        titleTextContent = value;
      });
    }
  }
  </code></pre>
  
  <p>The code above is properly functioning code that can be run directly. I have the problem that is TextField has property maxlines. If its null then it auto adjust as the text size grows/shrinks. And if we set it to constant as soon as we increase textContent it acts like scrollable in the widget. But what I want is something called "minLines" that is We start with default no of lines(like if we set max lines to constant) and then we can adjust the size of TextField if text grows(like if we set max lines to null). Also when the text content is beyond the range under the screen it becomes scrollable. 
  I would have handled that easily if I would be allowed to change maxLines attribute at runtime. I would have simply set a listener on textChange and managed the limits. But its final so I can edit that as well. What can I do?</p>