How to fix this Row nested in Column exception issue in Flutter?

49 views Asked by At

In my codes, Row widget nested in Column widget are causing exception at times. I searched and found that you can nest Row in Column however. So, I am unable to find the cause and more importantly the fix of the exception.

My main code has the following layout as shown in the diagram below: (Here, if Column widget is replaced by Row widget, shown by marking tick and cross, an exception occurs, and I can't figure out why and how to solve it!)

main_program_layout

Then, I tried with another program with the following layout:

example_program

In this example program, the first Row has two Text children and does not cause any error, unless we add more children or length of text sufficient to cause an overflow at the side edge. So, this cleared my doubt if it was possible to nest a Row in a Column: apparently we can.

Then I added another Row widget, which was fine until the content were Text with content short enough to fit horizontally, and then I replaced the Text child with a TextField which I need in my main layout as well, an exception occurred here as well.

What is the reason and how can I solve this? Below is the code of the second example layout:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late TextEditingController controller;
  String text = "";

  @override
  void initState() {
    super.initState();
    controller = TextEditingController();
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  bool? _isChecked = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          children: [
            const Text("First child of Column."),
            const Column(
              children: [
                Text("First child of Column nested within another Column"),
                Text(
                    "Second child of Column nested within another Column; making this line longer did not cause overflow at the side edge."),
              ],
            ),
            // Using enough children or long text in Row may cause overflow
            const Row(
              children: [
                Text("Text01"),
                Text("Text02"),
                Text("Text03"),
              ],
            ),
            Row(
              children: [
                TextField(
                  controller: controller,
                  onSubmitted: (String value) {
                    setState(() {
                      text = controller.text;
                    });
                  },
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

UPDATE 01:

I tried wrapping inside Flexible and Expanded the entire Row and in other only the children (I need both TextField and CheckboxListTile in a row) of Row both in Flexible, but nothing worked. One of the code I tried:

        Expanded(
          child: Row(
            children: [
              TextField(
                controller: controller,
                onSubmitted: (String value) {
                  setState(() {
                    text = controller.text;
                  });
                },
              ),
              CheckboxListTile(
                value: _isChecked,
                controlAffinity: ListTileControlAffinity.leading,
                onChanged: (bool? newValue) {
                  setState(() {
                    _isChecked = newValue;
                    if (_isChecked == true) {
                      //text = "Default Value 01";
                      /*
                  controller =
                      TextEditingController(text: "Default Value 01");
                  */
                      controller.text = "Default Value 01";
                    }
                    if (_isChecked == false) {
                      //text = "";
                      /*
                  controller = TextEditingController(text: "");
                  */
                      controller.clear();
                    }
                  });
                },
                title: Text("Checkbox"),
              ),
            ],
          ),
        ),
2

There are 2 answers

2
diegoveloper On BEST ANSWER

You just need to wrap your TextField inside the Expanded or Flexible widget:

            Row(
              children: [
                Flexible(
                  child: TextField(
                    controller: controller,
                    onSubmitted: (String value) {
                      setState(() {
                        text = controller.text;
                      });
                    },
                  ),
                ),
              ],
            ),

or if you are going to use only one item, like the TextField just remove the row and use the TextField directly.

UPDATE:

If you need the TextField and CheckboxListTile use this :

              Row(
                children: [
                  Expanded(
                    child: TextField(
                      controller: controller,
                      onSubmitted: (String value) {
                        setState(() {
                          text = controller.text;
                        });
                      },
                    ),
                  ),
                  Flexible(
                    child: CheckboxListTile(
                      value: _isChecked,
                      controlAffinity: ListTileControlAffinity.leading,
                      onChanged: (bool? newValue) {
                        setState(() {
                           _isChecked = newValue;
                          if (_isChecked == true) {
                            //text = "Default Value 01";
                            /*
                      controller =
                          TextEditingController(text: "Default Value 01");
                      */
                            controller.text = "Default Value 01";
                          }
                          if (_isChecked == false) {
                            //text = "";
                            /*
                      controller = TextEditingController(text: "");
                      */
                            controller.clear();
                          }
                        });
                      },
                      title: const Text("Checkbox"),
                    ),
                  ),
                ],
              ),
0
Ritu Nambath On

If you're encountering the error, you can resolve it by wrapping the TextField inside an Expanded or Flexible widget within the Row.

          Row(
              children: [
                TextField(
                  controller: controller,
                  onSubmitted: (String value) {
                    setState(() {
                      text = controller.text;
                    });
                  },
                ),
              ],
            )