flutterdartflutter-layout

Flutter: "RenderFlex children have non-zero flex but incoming height constraints are unbounded"


I want to have a ListView inside another widget when I wrap FutureBuilder in a Column in order to have a simple Row. I get this error:

The following assertion was thrown during performLayout():
I/flutter (13816): RenderFlex children have non-zero flex but incoming height constraints are unbounded.
I/flutter (13816): When a column is in a parent that does not provide a finite height constraint, for example, if it is
I/flutter (13816): in a vertical scrollable, it will try to shrink-wrap its children along the vertical axis. Setting a
I/flutter (13816): flex on a child (e.g. using Expanded) indicates that the child is to expand to fill the remaining
I/flutter (13816): space in the vertical direction.
I/flutter (13816): These two directives are mutually exclusive. If a parent is to shrink-wrap its child, the child
I/flutter (13816): cannot simultaneously expand to fit its parent.
I/flutter (13816): Consider setting mainAxisSize to MainAxisSize.min and using FlexFit.loose fits for the flexible
I/flutter (13816): children (using Flexible rather than Expanded). This will allow the flexible children to size
I/flutter (13816): themselves to less than the infinite remaining space they would otherwise be forced to take, and
I/flutter (13816): then will cause the RenderFlex to shrink-wrap the children rather than expanding to fit the maximum
I/flutter (13816): constraints provided by the parent.
I/flutter (13816): If this message did not help you determine the problem, consider using debugDumpRenderTree():

My code:

class ActivityShowTicketReplies extends StatefulWidget {
  final Map<String, dynamic> ticketData;

  ActivityShowTicketReplies({@required this.ticketData});

  @override
  State<StatefulWidget> createState() => ActivityShowTicketRepliesState();
}

class ActivityShowTicketRepliesState extends State<ActivityShowTicketReplies> {
  TicketsTableData get _ticket => TicketsTableData.fromJson(json.decode(widget.ticketData.values.toList()[0][0].toString()));

  @override
  Widget build(BuildContext context) {
    return ScopedModel(
      model: CounterModel(),
      child: Directionality(
        textDirection: TextDirection.rtl,
        child: Scaffold(
          body: Column(
            children: <Widget>[
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  Padding(
                    padding: const EdgeInsets.symmetric(vertical: 20.0),
                    child: RaisedButton(
                      color: Colors.indigo,
                      onPressed: () => BlocProvider.of<AppPagesBloc>(context).dispatch(FragmentNavigateEvent(routeName: FRAGMENT_NEW_TICKET)),
                      shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(50.0)),
                      child: Container(
                        child: Text(
                          'new ticket',
                          style: AppTheme(context).caption().copyWith(color: Colors.white),
                        ),
                      ),
                    ),
                  ),
                ],
              ),
              FutureBuilder(
                future: Provider.of<TicketRepliesTableDao>(context).find(ticketId: _ticket.id),
                builder: (context, snapshot) {
                  if (snapshot.connectionState == ConnectionState.done) {
                    if (snapshot.hasData) {
                      final List<TicketRepliesTableData> ticketReplies = snapshot.data;
                      if (ticketReplies.isNotEmpty) {
                        return Column(
                          children: <Widget>[
                            Card(
                              clipBehavior: Clip.antiAlias,
                              color: Colors.grey[50],
                              margin: EdgeInsets.all(10.0),
                              child: InkWell(
                                child: Stack(
                                  children: <Widget>[
                                    Column(
                                      children: <Widget>[
                                        Padding(
                                          padding: const EdgeInsets.symmetric(vertical: 12.0),
                                          child: ListTile(
                                            title: Padding(
                                              padding: const EdgeInsets.symmetric(vertical: 5.0),
                                              child: Text(
                                                'subject',
                                                style: AppTheme(context).caption().copyWith(fontFamily: 'ShabnamBold'),
                                              ),
                                            ),
                                            subtitle: Text(
                                              _ticket.subject,
                                              style: AppTheme(context).caption(),
                                            ),
                                          ),
                                        ),
                                        Container(
                                          height: 30.0,
                                          margin: EdgeInsets.zero,
                                          width: double.infinity,
                                          color: Colors.grey[200],
                                          child: Row(
                                            mainAxisAlignment: MainAxisAlignment.center,
                                            children: <Widget>[
                                              
                                            ],
                                          ),
                                        ),
                                      ],
                                    ),
                                    Align(
                                      alignment: Alignment.topLeft,
                                      child: Container(
                                          margin: EdgeInsets.only(top: 10.0),
                                          constraints: BoxConstraints(
                                            minWidth: 70.0,
                                          ),
                                          height: 20.0,
                                          width: 70.0,
                                          decoration: BoxDecoration(
                                              color: Colors.green[200],
                                              borderRadius: BorderRadius.only(
                                                topRight: Radius.circular(5.0),
                                                bottomRight: Radius.circular(5.0),
                                              )),
                                          child: Center(
                                            child: Text(
                                              'status',
                                              style: AppTheme(context).overLine().copyWith(fontFamily: 'ShabnamBold', color: Colors.black),
                                            ),
                                          )),
                                    ),
                                  ],
                                ),
                                onTap: () {},
                              ),
                            ),
                            Expanded(
                              child: ListView.builder(
                                itemBuilder: (context, index) {
                                  return Card(
                                    clipBehavior: Clip.antiAlias,
                                    child: Padding(
                                      padding: const EdgeInsets.all(20.0),
                                      child: Column(
                                        mainAxisAlignment: MainAxisAlignment.start,
                                        crossAxisAlignment: CrossAxisAlignment.start,
                                        children: <Widget>[
                                          Row(
                                            children: <Widget>[
                                              Text(
                                                ticketReplies[index].createdAt,
                                                style: AppTheme(context).caption().copyWith(fontFamily: 'ShabnamLight'),
                                              ),
                                            ],
                                          ),
                                          ListTile(
                                            title: Text(ticketReplies[index].reply),
                                          ),
                                        ],
                                      ),
                                    ),
                                  );
                                },
                                itemCount: ticketReplies.length,
                              ),
                            ),
                          ],
                        );
                      } else {
                        return Center(
                          child: Text(
                            'there isn't any reply message',
                            style: AppTheme(context).caption(),
                          ),
                        );
                      }
                    } else {
                      return _loader(context, 'no reply');
                    }
                  } else
                    return _loader(context, Strings.pleaseWait);
                },
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _loader(BuildContext context,String message) {
    return Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            ColorLoader3(
              radius: 25.0,
              dotRadius: 5.0,
            ),
            Padding(
              padding: const EdgeInsets.all(3.0),
              child: Text(
                Strings.pleaseWait,
                style: AppTheme(context).caption().copyWith(color: Colors.red[900]),
              ),
            ),
          ],
        ));
  }
}

Solution

  • Wrap your Column inside an Expanded or SizedBox (with some height) like this:

    Expanded(
      child: Column(...)
    )
    

    OR

    SizedBox(
      height: 200, // Some height
      child: Column(...),
    )
    

    Note that a Flex class or sub-class (like Column) should not be child of other Flex classes, and their parent class needs to be of type Flexible (i.e. inherit it, like Expanded), else, Flex-class gets unbounded (and remaining space cannot be calculated) which causes no direct issue till yet another child tries to calculate and/or fill space.