1

I was trying to receive data from an API in a ListView Builder using user input to display how many tickets to be displayed.. This is where I am trying to reflect the user input. Everytime I am using the textfield before the listview builder I am receving error

    import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

class Ticket {
  Ticket({
    this.tickets,
  });

  List<List<List<int>>> tickets;

  factory Ticket.fromJson(Map<String, dynamic> json) => Ticket(
        tickets: List<List<List<int>>>.from(json["tickets"].map((x) =>
            List<List<int>>.from(
                x.map((x) => List<int>.from(x.map((x) => x)))))),
      );

  Map<String, dynamic> toJson() => {
        "tickets": List<dynamic>.from(tickets.map((x) => List<dynamic>.from(
            x.map((x) => List<dynamic>.from(x.map((x) => x)))))),
      };
}

class TicketPage extends StatefulWidget {
  @override
  _TicketPageState createState() => _TicketPageState();
}

class _TicketPageState extends State<TicketPage> {
  String _nos = '0';
  Ticket ticketList;
  String apiResult;
  Map<String, bool> cellStatus = {};
  final numCon = TextEditingController();

  @override
  void initState() {
    super.initState();
    _getNumbers();
    numCon.addListener(_updateUserInput);
  }

  _updateUserInput() {
    _nos = numCon.text;
  }

  @override
  void dispose() {
// Clean up the controller when the widget is removed from the widget tree.
// This also removes the listener.
    numCon.dispose();
    super.dispose();
  }

  _getNumbers() async {
    var result = await http
        .post(
            'https://tickets-qzd55332wa-de.a.run.app/generateTickets?ticketsRequired=$_nos')
        .then((result) {
      //Waits for the API response and assigns to apiResult variable
      setState(() {
        apiResult = result.body;
      });
    });
  }

  // List tick = [
  //   {
  //     'tickets': [
  //       [
  //         [11, 5, 7, 10, 28, 9, 7, 74, 59],
  //         [1, 15, 7, 10, 8, 79, 27, 74, 9],
  //         [71, 5, 7, 20, 18, 9, 77, 74, 79],
  //       ],
  //       [
  //         [21, 5, 7, 80, 8, 9, 7, 74, 49],
  //         [31, 15, 7, 10, 18, 79, 7, 74, 19],
  //         [71, 5, 7, 20, 18, 79, 77, 74, 29],
  //       ],
  //     ]
  //   },
  // ];

  @override
  Widget build(BuildContext context) {
    var h = MediaQuery.of(context).size.height;
    var w = MediaQuery.of(context).size.width;

    if (apiResult == null) {
      return Scaffold(body: Center(child: CircularProgressIndicator()));
    } else {
      //Get an instance of Ticket from the API assigned to apiResponse variable
      ticketList = Ticket.fromJson(json.decode(apiResult));
      print('Tickets: ${ticketList.tickets}');

      return Scaffold(
        body: SafeArea(
          child: Column(
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.all(28.0),
                child: Container(
                  child: TextField(
                    controller: numCon,
                    decoration: InputDecoration(
                      hintText: 'nos',
                    ),
                  ),
                ),
              ),
              RaisedButton(onPressed: () {
                setState(() {
                  _getNumbers();
                });
              }),
              Center(
                child: Padding(
                  padding: const EdgeInsets.all(20.0),
                  child: Container(
                    decoration: BoxDecoration(
                        border: Border.all(
                      color: Colors.black,
                    )),
                    child: ListView.builder(
                      itemCount: ticketList.tickets.length,
                      itemBuilder: (BuildContext context, index) {
                        List tripleNumbersList = [];
                        List<Widget> cells = [];
                        List<Widget> rows = [];

                        //Get the lists of lists inside the 'tickets' list
                        tripleNumbersList = ticketList.tickets[index];
                        //Iterates over each list with other 3 lists
                        for (int j = 0; j < tripleNumbersList.length; j++) {
                          //Get one of the 3 lists
                          List<int> list = tripleNumbersList[j];
                          //Iterates over the list of numbers
                          for (int k = 0; k < list.length; k++) {
                            //Adds a Widget to 'cells; list for each number
                            cells.add(Container(
                                height: 40,
                                width: 40,
                                decoration: BoxDecoration(
                                  border: Border.all(
                                    color: Colors.black,
                                  ),
                                  //color: Colors.pink
                                ),
                                child: GestureDetector(
                                  onTap: () {
                                    print('Working');
                                    if (cellStatus['$j$k'] ?? true) {
                                      print('Working');
                                      setState(() {
                                        cellStatus.addAll({'$j$k': false});
                                      });
                                    }
                                  },
                                  child: list[k] != 0
                                      ? Text(
                                          ' ${list[k]}  ',
                                          style: TextStyle(
                                              fontSize: 18.0,
                                              fontWeight: FontWeight.bold),
                                        )
                                      : Text(''),
                                )));
                          }
                          //Adds the list of 'cells' in the 'rows' list
                          rows.add(Row(children: cells));
                          cells = [];
                        }
                        //Adds a empty row to make space
                        rows.add(Row(children: [
                          Container(
                            height: 10,
                          )
                        ]));

                        return Center(
                          child: Container(
                            height: h / 5,
                            decoration: BoxDecoration(
                              border: Border.all(
                                color: Colors.black,
                              ),
                              //color: Colors.pink
                            ),
                            child: Column(
                              //Adds the list of rows to the column
                              children: rows,
                            ),
                          ),
                        );
                      },
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      );
    }
  }
}

And it is throwing exception as

RenderBox was not laid out: RenderCustomPaint#aecb2 relayoutBoundary=up8 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1694 pos 12: 'hasSize'
The relevant error-causing widget was
    ListView 
RenderBox was not laid out: RenderPadding#d9b88 relayoutBoundary=up1 NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1694 pos 12: 'hasSize'
The relevant error-causing widget was
    Scaffold 

I hope I could explain the problem the and wish to see help me out solve this issue. I am stuck to this problem a from a lot.

4
  • Please have a look @JideGuru Commented Jul 17, 2020 at 11:39
  • I did went through all these example and now I am stuck to this.... Tried using the text controller still the error pops out. That is why I am in search of help to this problem @dev-aentgs Commented Jul 17, 2020 at 13:11
  • This one covers the steps better : Handle changes to a text field . Can you post updated code with TextEditingController ? Commented Jul 17, 2020 at 13:16
  • I have made the changes... Please look at it @dev-aentgs Commented Jul 17, 2020 at 13:27

1 Answer 1

1

The error occurs due to nesting of ListView inside Column.

The above code can be modified to wrap ListView in Expanded. With reference to this answer

Example :

  @override
  Widget build(BuildContext context) {
    return _buildList(context);
  }

  Widget _buildList(BuildContext context) {
    var h = MediaQuery.of(context).size.height;

    if (apiResult == null) {
      return Scaffold(body: Center(child: CircularProgressIndicator()));
    } else {
      //Get an instance of Ticket from the API assigned to apiResponse variable
      ticketList = Ticket.fromJson(json.decode(apiResult));
      print('${ticketList.tickets.length} Tickets: ${ticketList.tickets}');

      return SafeArea(
        child: Scaffold(
          appBar: AppBar(
            title: Text('SO 62967820'),
          ),
          body: Column(
            children: [
              Padding(
                padding: const EdgeInsets.all(28.0),
                child: Container(
                  child: TextField(
                    controller: numCon,
                    decoration: InputDecoration(
                      hintText: 'nos',
                    ),
                  ),
                ),
              ),
              RaisedButton(
                  child: Text('Generate'),
                  onPressed: () {
                    setState(() {
                      _getNumbers();
                    });
                  }),
              Expanded(
                child: ListView.builder(
                  itemCount: ticketList.tickets.length,
                  itemBuilder: (BuildContext context, index) {
                    List tripleNumbersList = [];
                    List<Widget> cells = [];
                    List<Widget> rows = [];

                    //Get the lists of lists inside the 'tickets' list
                    tripleNumbersList = ticketList.tickets[index];
                    //Iterates over each list with other 3 lists
                    for (int j = 0; j < tripleNumbersList.length; j++) {
                      //Get one of the 3 lists
                      List<int> list = tripleNumbersList[j];
                      //Iterates over the list of numbers
                      for (int k = 0; k < list.length; k++) {
                        //Adds a Widget to 'cells; list for each number
                        cells.add(Container(
                            height: 40,
                            width: 40,
                            decoration: BoxDecoration(
                              border: Border.all(
                                color: Colors.black,
                              ),
                              //color: Colors.pink
                            ),
                            child: GestureDetector(
                              onTap: () {
                                print('Working');
                                if (cellStatus['$j$k'] ?? true) {
                                  print('Working');
                                  setState(() {
                                    cellStatus.addAll({'$j$k': false});
                                  });
                                }
                              },
                              child: list[k] != 0
                                  ? Text(
                                      ' ${list[k]}  ',
                                      style: TextStyle(
                                          fontSize: 18.0,
                                          fontWeight: FontWeight.bold),
                                    )
                                  : Text(''),
                            )));
                      }
                      //Adds the list of 'cells' in the 'rows' list
                      rows.add(Row(children: cells));
                      cells = [];
                    }
                    //Adds a empty row to make space
                    rows.add(Row(children: [
                      Container(
                        height: 10,
                      )
                    ]));

                    return Center(
                      child: Container(
                        height: h / 5,
                        decoration: BoxDecoration(
                          border: Border.all(
                            color: Colors.black,
                          ),
                          //color: Colors.pink
                        ),
                        child: Column(
                          //Adds the list of rows to the column
                          children: rows,
                        ),
                      ),
                    );
                  },
                ),
              ),
            ],
          ),
        ),
      );
    }
  }
Sign up to request clarification or add additional context in comments.

3 Comments

But what role did that expanded widget play
Not completely sure but from my understanding of the error and the explanation from this answer, the Expanded widget took care of allocating appropriate height for the ListView in the parent Column. @PratyaySinha
Hey!! Would appreciate if you could just have a look at this problem that I am facing stackoverflow.com/questions/68603763/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.