Search code examples
fluttertextfield

showing TextFields in Row and Column problem - Flutter


i want TextFields to be in a Row or a Column widget based on the screen width. TextFields in a row need to be in another widget like expanded to limit their width so they don't make any errors. but when they are in a Column widget they disappear and must delete the Expanded widget.

I used Flex widget to change the direction based on width. i thought about creating two separated widgets but its not clean. this is the code witch works when direction is vertical:

Flex(
            direction: MediaQuery.sizeOf(context).width < 500
                ? Axis.vertical
                : Axis.horizontal,
            // direction: Axis.vertical,
            children: [
              TextField(
                decoration: const InputDecoration(
                  border: OutlineInputBorder(),
                  labelText: 'name',
                  floatingLabelAlignment: FloatingLabelAlignment.start,
                  isDense: true,
                ),
                textAlign: TextAlign.right,
                controller: costomerNameCon,
              ),
              const SizedBox(
                width: 10,
              ),
              TextField(
                decoration: const InputDecoration(
                    border: OutlineInputBorder(),
                    labelText: 'phone',
                    floatingLabelAlignment: FloatingLabelAlignment.start,
                    isDense: true,
                    labelStyle: TextStyle()),
                textAlign: TextAlign.right,
                controller: costomerPhoneCon,
              ),
              const SizedBox(
                width: 10,
              ),
              TextField(
                decoration: const InputDecoration(
                    border: OutlineInputBorder(),
                    labelText: 'email',
                    floatingLabelAlignment: FloatingLabelAlignment.start,
                    isDense: true,
                    labelStyle: TextStyle()),
                textAlign: TextAlign.right,
                controller: costomerEmailCon,
              ),
            ],
          )

is there any way that i can handle it?


Solution

  • I believe this is a common problem with Flex or Row widgets: An InputDecorator, which is typically created by a TextField, cannot have an unbounded width. Children widgets shouldn't be given an unbounded width. Try changing the mainAxisSize to min since the default is max and max forces the children to take up as much space as possible.

    Flex(
                direction: MediaQuery.sizeOf(context).width < 500
                    ? Axis.vertical
                    : Axis.horizontal,
                // direction: Axis.vertical,
                mainAxisSize: MainAxisSize.min, // add this
                children: [
                  TextField(
                    decoration: const InputDecoration(
                      border: OutlineInputBorder(),
                      labelText: 'name',
                      floatingLabelAlignment: FloatingLabelAlignment.start,
                      isDense: true,
                    ),
                    textAlign: TextAlign.right,
                    controller: costomerNameCon,
                  ),
                  const SizedBox(
                    width: 10,
                  ),
                  TextField(
                    decoration: const InputDecoration(
                        border: OutlineInputBorder(),
                        labelText: 'phone',
                        floatingLabelAlignment: FloatingLabelAlignment.start,
                        isDense: true,
                        labelStyle: TextStyle()),
                    textAlign: TextAlign.right,
                    controller: costomerPhoneCon,
                  ),
                  const SizedBox(
                    width: 10,
                  ),
                  TextField(
                    decoration: const InputDecoration(
                        border: OutlineInputBorder(),
                        labelText: 'email',
                        floatingLabelAlignment: FloatingLabelAlignment.start,
                        isDense: true,
                        labelStyle: TextStyle()),
                    textAlign: TextAlign.right,
                    controller: costomerEmailCon,
                  ),
                ],
              )
    

    And now the text fields will be overflowing on the right. So best to wrap each in a Flexible widget to constrain to the screen size:

    
    Flex(
                  direction: MediaQuery.sizeOf(context).width < 500
                    ? Axis.vertical
                    : Axis.horizontal,
                  mainAxisSize: MainAxisSize.min,
          children: [
                  Flexible(child: TextField(
                    decoration: const InputDecoration(
                      border: OutlineInputBorder(),
                      labelText: 'name',
                      floatingLabelAlignment: FloatingLabelAlignment.start,
                      isDense: true,
                    ),
                    textAlign: TextAlign.right,
                    controller: costomerNameCon,
                  ),),
                  const SizedBox(
                    width: 10,
                  ),
                  Flexible(child: TextField(
                    decoration: const InputDecoration(
                        border: OutlineInputBorder(),
                        labelText: 'phone',
                        floatingLabelAlignment: FloatingLabelAlignment.start,
                        isDense: true,
                        labelStyle: TextStyle()),
                    textAlign: TextAlign.right,
                    controller: costomerPhoneCon,
                  )),
                  const SizedBox(
                    width: 10,
                  ),
                  Flexible(child: TextField(
                    decoration: const InputDecoration(
                        border: OutlineInputBorder(),
                        labelText: 'email',
                        floatingLabelAlignment: FloatingLabelAlignment.start,
                        isDense: true,
                        labelStyle: TextStyle()),
                    textAlign: TextAlign.right,
                    controller: costomerEmailCon,
                  )),
                ],
          
                )