xpetta
xpetta

Reputation: 718

Getting the following error "RenderFlex children have non-zero flex but incoming height constraints are unbounded" in Flutter

I'm getting the below errors when I'm trying to add a ListView widget as a child to a Column. I did check out few solutions, but couldn't get it worked out.

I have copied excerpts from the error.

════════ Exception caught by rendering library ═════════════════════════════════
The following assertion was thrown during performLayout():
RenderFlex children have non-zero flex but incoming height constraints are unbounded.

When a column is in a parent that does not provide a finite height constraint, for example if it is in a vertical scrollable, it will try to shrink-wrap its children along the vertical axis. Setting a flex on a child (e.g. using Expanded) indicates that the child is to expand to fill the remaining space in the vertical direction.
These two directives are mutually exclusive. If a parent is to shrink-wrap its child, the child cannot simultaneously expand to fit its parent.

════════ Exception caught by rendering library ═════════════════════════════════
RenderBox was not laid out: RenderRepaintBoundary#c4e1c NEEDS-LAYOUT NEEDS-PAINT
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1930 pos 12: 'hasSize'

The relevant error-causing widget was
Column
lib/screens/app_home.dart:51
════════════════════════════════════════════════════════════════════════════════

The ListView is getting built by a StreamBuilder below is the code for the same.

final coursesCollection = FirebaseFirestore.instance.collection('courses').limit(10).where('courseLive', isEqualTo: true);

class CourseStream extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamBuilder<QuerySnapshot>(
      stream: coursesCollection.snapshots(),
      builder: (context, snapshot) {
        if (!snapshot.hasData) {
          if (snapshot.connectionState == ConnectionState.waiting) {
            return Center(
              child: CircularProgressIndicator(backgroundColor: kBrandColor),
            );
          }
        }

        final courseListStream = snapshot.data!.docs.map((course) {
          return CourseData.fromDocument(course);
        }).toList();

        List<BadgedCourseCard> courseCards = [];

        for (var course in courseListStream) {
          final courseDocID = course.courseDocID;
          final courseID = course.courseID;
          final courseTitle = course.courseTitle;
          final courseDescription = course.courseDescription;
          final courseSubTitle = course.courseSubTitle;
          final courseBadge = course.courseBadge;
          final courseLevel = course.courseLevel;
          final coursePaid = course.coursePaid;
          final courseImage = course.courseImage;
          final courseBgColor = hexToColor(course.courseBackgroundColor.toString());
          final courseBgColor1 = hexToColor(course.courseBgColor1.toString());
          final courseBgColor2 = hexToColor(course.courseBgColor2.toString());
          final courseFgColor = hexToColor(course.courseFgColor.toString());
          final courseDeliveryFormat = course.courseDeliveryFormat;
          final courseLive = course.courseLive;

          final badgedCourseCard = BadgedCourseCard(
            courseTitle: courseTitle.toString(),
            courseTitleTextColor: courseFgColor,
            cardBackgroundColor: courseBgColor,
            courseImage: courseImage.toString(),
            courseCardTapped: () => print("Course Card Tapped"),
            courseBookmarkTapped: () => print("Course Bookmark Tapped"),
          );

        return Expanded(
          child: ListView(
            physics: BouncingScrollPhysics(),
            scrollDirection: Axis.horizontal,
            children: courseCards,
          ),
        );
      },
    );
  }
}

Listed below is the code where I'm trying to consume the CourseStream class. This is where the error is getting triggered.

class AppHome extends StatefulWidget {
  @override
  _AppHomeState createState() => _AppHomeState();
}

class _AppHomeState extends State<AppHome> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // drawer: AppDrawer(),
      appBar: AppBar(
        backgroundColor: Colors.transparent,
        elevation: 0.0,
        leading: Padding(
          padding: EdgeInsets.only(left: 2.5.w),
          child: IconButton(
            onPressed: () => Navigator.of(context).push(ScaledAnimationPageRoute(AppDrawer())),
            icon: Icon(
              Icons.sort,
              color: Theme.of(context).iconTheme.color,
              size: 6.5.w,
            ),
          ),
        ),
        actions: <Widget>[
          Padding(
            padding: EdgeInsets.only(right: 2.5.w),
            child: IconButton(
              onPressed: null,
              icon: Icon(
                Icons.search,
                color: Theme.of(context).iconTheme.color,
                size: 6.5.w,
              ),
            ),
          ),
        ],
      ),
      body: Padding(
        padding: EdgeInsets.symmetric(horizontal: 5.w),
        child: SingleChildScrollView(
          physics: BouncingScrollPhysics(),
          child: Column(
            children: [
              CardHeader(
                leadingText: "Courses",
                trailingText: "View All",
              ),
              SizedBox(height: 1.h),
              CourseStream(),
              SizedBox(height: 2.h),
            ],
          ),
        ),
      ),
    );
  }
}

If you need any further details, please do let me know.

Really appreciate, if anyone could help me in getting this issue fixed. Thanks a lot in advance for your time and help.

Upvotes: 2

Views: 5281

Answers (2)

xpetta
xpetta

Reputation: 718

I did wrap the ListView with a SizedBox widget this fixed the issue.

return SizedBox(
       height: 20.5.h,
       child: ListView(
         physics: BouncingScrollPhysics(),
         scrollDirection: Axis.horizontal,
         children: courseCards,
      ),
);

Upvotes: 0

Michael Horn
Michael Horn

Reputation: 4089

It's because your Column is positioned inside a SingleChildScrollView, which has unbounded size, but contains an Expanded widget (CourseStream), which tries to take up as much size as possible. Basically the Expanded widget doesn't know when to stop expanding.

As far as how to help you achieve what you're trying to do, I'm not quite clear on what the desired behavior is, but essentially you'll need to define the height of your list items.

It seems like you might be trying to achieve a paging effect - if that's the case, then you might find the PageView widget helpful: https://api.flutter.dev/flutter/widgets/PageView-class.html

Upvotes: 2

Related Questions