Home > Enterprise >  How to maximise TextFormField in a Dialog/Form with Flutter?
How to maximise TextFormField in a Dialog/Form with Flutter?

Time:08-07

I have a Dialog/Form like this (Flutter 3.0.5 - Web Chrome):

Future<void> showInformationDialog(BuildContext context) async {
    double screenWidth = MediaQuery.of(context).size.width;
    double screenHeight = MediaQuery.of(context).size.height;
    return await showDialog(
        context: context,
        builder: (context) {
          return StatefulBuilder(builder: (context, setState) {
            return AlertDialog(
              insetPadding: const EdgeInsets.all(10),
              content: Row(children: [
                SizedBox(
                    width: screenWidth * 0.6,
                    height: screenHeight * 0.5,
                    child: Form(
                      key: _formKey,
                      child: Column(
                        mainAxisSize: MainAxisSize.min,
                        children: [
                          TextFormField(
                            controller: _titleEditingController,
                            validator: (value) {
                              return value!.isNotEmpty ? null : "Title";
                            },
                            decoration: const InputDecoration(hintText: "Title"),
                          ),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Expanded(
                                child:
                                    TextField(
                                      enabled: false,
                                      controller: _dateController,
                                    ),
                              ),
                              ElevatedButton(
                                onPressed: () {
                                  _restorableDatePickerRouteFuture.present();
                                },
                                child: const Icon(Icons.calendar_month),
                              )
                            ],
                          ),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Expanded(
                                child:
                                TextField(
                                  enabled: false,
                                  controller: _timeController,
                                ),
                              ),
                              ElevatedButton(
                                onPressed: () {
                                  _displayTimeDialog();
                                },
                                child: const Icon(Icons.access_time_outlined),
                              )
                            ],
                          ),
                          const SizedBox(height: 30,),
                          TextFormField(
                            controller: _detailsEditingController,
                            keyboardType: TextInputType.multiline,
                            maxLines: null,
                            decoration: const InputDecoration(
                                hintText: "Enter Task Details",
                                border: OutlineInputBorder(
                                    borderSide: BorderSide(width: 2)
                                ),
                            ),
                          ),
                        ],
                  )))]),
              title: const Text('Create Task'),
              actions: <Widget>[
                InkWell(
                  child: const Text('OK'),
                  onTap: () {
                    if (_formKey.currentState!.validate()) {
                      Navigator.of(context).pop();
                    }
                  },
                ),
              ],
            );
          });
        });
  }

and I have added a percentage width/height to it. However the TextFormField does not fill the whole available space automatically (image below), and you can only predefine the number of lines which won't work for all cases. How can I make the TextFormField able to fill the available space?

enter image description here

If I add what Yeasin suggests in his solution, I get:

The hitTest() method was called on this RenderBox: RenderConstrainedBox#c7750 relayoutBoundary=up1: needs compositing creator: ConstrainedBox ← Align ← MediaQuery ← Padding ← AnimatedPadding ← Dialog ← AlertDialog ← StatefulBuilder ← Builder ← DefaultTextStyle ← CaptureAll ← MediaQuery ← ⋯ parentData: offset=Offset(0.0, 0.0) (can use size) constraints: BoxConstraints(0.0<=w<=1491.0, 0.0<=h<=1311.0) size: MISSING additionalConstraints: BoxConstraints(280.0<=w<=Infinity, 0.0<=h<=Infinity) Although this node is not marked as needing layout, its size is not set. A RenderBox object must have an explicit size before it can be hit-tested. Make sure that the RenderBox in question sets its size during layout. at Object.throw [as throw] (http://localhost:38447/dart_sdk.js:5080:11)

CodePudding user response:

Use Expanded with maxLines:null and expands: true,

Expanded(
    child: TextFormField(
  keyboardType: TextInputType.multiline,
  expands: true,
  maxLines: null,
  minLines: null,
  decoration: const InputDecoration(
    hintText: "Enter Task Details",
    border: OutlineInputBorder(
      borderSide: BorderSide(width: 2),
    ),
  ),
)),

enter image description here

Full dialog

  Future<void> showInformationDialog(BuildContext context) async {
    double screenWidth = MediaQuery.of(context).size.width;
    double screenHeight = MediaQuery.of(context).size.height;
    return await showDialog(
        context: context,
        builder: (context) {
          return StatefulBuilder(builder: (context, setState) {
            return AlertDialog(
              insetPadding: const EdgeInsets.all(10),
              content: Row(children: [
                SizedBox(
                  // color: Colors.cyanAccent.withOpacity(.3),
                  width: screenWidth * 0.6,
                  height: screenHeight * 0.5,
                  child: Form(
                    child: Column(
                      mainAxisSize: MainAxisSize.max,
                      children: [
                        TextFormField(
                          validator: (value) {
                            return value!.isNotEmpty ? null : "Title";
                          },
                          decoration: const InputDecoration(hintText: "Title"),
                        ),
                        Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: [
                            Expanded(
                              child: TextField(
                                enabled: false,
                              ),
                            ),
                            ElevatedButton(
                              onPressed: () {},
                              child: const Icon(Icons.calendar_month),
                            )
                          ],
                        ),
                        Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: [
                            Expanded(
                              child: TextField(
                                enabled: false,
                              ),
                            ),
                            ElevatedButton(
                              onPressed: () {},
                              child: const Icon(Icons.access_time_outlined),
                            )
                          ],
                        ),
                        const SizedBox(
                          height: 30,
                        ),
                        Expanded(
                            child: TextFormField(
                          keyboardType: TextInputType.multiline,
                          expands: true,
                          maxLines: null,
                          minLines: null,
                          decoration: const InputDecoration(
                            hintText: "Enter Task Details",
                            border: OutlineInputBorder(
                              borderSide: BorderSide(width: 2),
                            ),
                          ),
                        )),
                      ],
                    ),
                  ),
                )
              ]),
              title: const Text('Create Task'),
              actions: <Widget>[
                InkWell(
                  child: const Text('OK'),
                  onTap: () {},
                ),
              ],
            );
          });
        });
  }
  • Related