skip to Main Content

Im trying to put a gridview inside a row for flutter web development, but I got a few errors

Another exception was thrown: Vertical viewport was given unbounded height.
36
Another exception was thrown: Assertion failed: file:///C:/dev/flutter/packages/flutter/lib/src/rendering/box.dart:1972:12
Another exception was thrown: Cannot hit test a render box that has never been laid out.

There is the code:

import 'package:cleanvideos/extensions/theme_extesion.dart';
import 'package:cleanvideos/extensions/widget_layout_extension.dart';
import 'package:cleanvideos/models/contents/video_model.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

class ContentViewBuilder extends StatefulWidget {
  final String? title;
  final String? subtitle;
  final String? label;
  final List<ModelVideo> videos;
  final EdgeInsets? titlePadding;
  const ContentViewBuilder({
    super.key,
    this.title,
    this.subtitle,
    this.label,
    required this.videos,
    this.titlePadding,
  });

  @override
  State<ContentViewBuilder> createState() => _ContentViewBuilderState();
}

class _ContentViewBuilderState extends State<ContentViewBuilder> {
  bool isAudioView = false;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(), //TODO Implementar AppBar
      body: Column(
        children: [
          Row(
            crossAxisAlignment: CrossAxisAlignment.end,
            children: [
              Text(
                widget.label ?? "",
                style:
                    context.textTheme.titleMedium?.copyWith(color: Colors.grey),
              ),
              Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(widget.title ?? "",
                      style: context.textTheme.titleLarge
                          ?.copyWith(fontWeight: FontWeight.bold)),
                  Text(
                    widget.subtitle ?? "",
                    style: context.textTheme.titleLarge
                        ?.copyWith(color: Colors.grey),
                  )
                ],
              ).withPadding(const EdgeInsets.only(left: 16))
            ],
          ).withPadding(widget.titlePadding ?? const EdgeInsets.only(left: 16)),
          const Divider(
            height: 0,
            color: Color(0xff0038B8),
          ).withPadding(const EdgeInsets.only(top: 16)),
          Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Column(
                mainAxisAlignment: MainAxisAlignment.start,
                children: [
                  FilledButton(
                      style: FilledButton.styleFrom(
                          backgroundColor: !isAudioView
                              ? const Color(0xffebeffa)
                              : Colors.transparent,
                          shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(8.0),
                          ),
                          fixedSize: const Size(114, 43)),
                      onPressed: () {
                        setState(() {
                          isAudioView = false;
                        });
                      },
                      child: Text(
                        "Videos",
                        style: TextStyle(
                            color: !isAudioView
                                ? const Color(0xff0038B8)
                                : const Color(0xff7f9bdb)),
                      )),
                  FilledButton(
                      style: FilledButton.styleFrom(
                          backgroundColor: isAudioView
                              ? const Color(0xffebeffa)
                              : Colors.transparent,
                          shape: RoundedRectangleBorder(
                            borderRadius: BorderRadius.circular(8.0),
                          ),
                          fixedSize: const Size(114, 43)),
                      onPressed: () {
                        setState(() {
                          isAudioView = true;
                        });
                      },
                      child: Text(
                        "Músicas",
                        style: TextStyle(
                            color: isAudioView
                                ? const Color(0xff0038B8)
                                : const Color(0xff7f9bdb)),
                      ))
                ],
              ).withPadding(
                  const EdgeInsets.only(left: 62, top: 47, right: 24)),
              const SizedBox(
                height: 691,
                child: VerticalDivider(
                  thickness: 1,
                  indent: 0,
                  endIndent: 0,
                  color: Color(0xff0038B8),
                ),
              ),
            ],
          )
        ],
      ),
    );
  }
}

class GridContentView extends StatelessWidget {
  final bool isAudioView;
  const GridContentView({super.key, required this.isAudioView});

  @override
  Widget build(BuildContext context) {
    return SizedBox(
        width: 1140,
        child: Expanded(
          child: SingleChildScrollView(
            child: GridView.count(
              crossAxisCount: isAudioView ? 5 : 3,
              crossAxisSpacing: 16,
              mainAxisSpacing: 16,
              children: List.generate(10, (index) {
                return Container(
                  height: 300,
                  width: isAudioView ? 200 : 500,
                  color: Colors.red,
                );
              }),
            ),
          ),
        ));
  }
} 

I tried expanded and sizedBox, but all of them got me the same error

3

Answers


  1. That part causes that error, nested scroll views:

    SingleChildScrollView(
                child: GridView()
              ) 
    
    1. Give The Grid View an Intrinsic Height using Widgets like Container or SizedBox

    2. if the Grid View’s scroll direction is vertical:

    set pysics of the GridView to NeveScrollableScrollPhysics() and shrinkWrap to true.

    Fix

    SingleChildScrollView(
     child: Container(
         height : MediaQuery.of(context).size.height/2,  // any height
         child: GridView.count(
             physics: NeverScrollableScrollPyhsics(),
             shrinkWrap: true,
             .....
                 )
       )
    

    Hope it helps you.

    Login or Signup to reply.
  2. The error is being thrown because the widget is demanding a finite space and you are giving an infinite space. In Flutter when you place a GridView (or any scrollable widget) inside a layout that doesn’t provide bounded constraints, like a Row or another GridView, you’ll encounter these issues.

    In your code, the GridView is placed inside a SingleChildScrollView wrapped by an Expanded widget in a SizedBox, which itself is unbounded vertically in this context.

    Here is the correct code:

    class GridContentView extends StatelessWidget {
      final bool isAudioView;
      const GridContentView({super.key, required this.isAudioView});
    
      @override
      Widget build(BuildContext context) {
        return Expanded( 
          child: SizedBox(
            width: 1140,
            child: GridView.builder(
              shrinkWrap: true,
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: isAudioView ? 5 : 3,
                crossAxisSpacing: 16,
                mainAxisSpacing: 16,
              ),
              itemCount: 10,
              itemBuilder: (context, index) {
                return Container(
                  height: 300,
                  color: Colors.red,
                );
              },
            ),
          ),
        );
      }
    }
    
    Login or Signup to reply.
  3. The unbounded height or width error usually comes up when the parent widget does not constraint their children, and one of the child requires to be unbounded (needing infinite height for scrolling). In your example, you have provided a SingleChildScrollView (which is a scrollable widget that does not constraint their child) to GridView (which is a scrollable widget and can take infinite space to scroll). And we cant have infinite scrollable user area thats what flutter is trying to warn you.

    To solve this, you can either provide shrinkWrap: true with NeverScrollableScrollPhysics which will load and determine the constraints of all the children of GridView. But this is not recommended with large amount of children as it remove lazy building feature of GridView.

    SizedBox(
      width: 1140,
      child: SingleChildScrollView(
        child: GridView.count(
          crossAxisCount: isAudioView ? 5 : 3,
          crossAxisSpacing: 16,
          mainAxisSpacing: 16,
          shrinkWrap: true,
          physics: const NeverScrollableScrollPhysics(),
          children: List.generate(10, (index) {
            return Container(
              height: 300,
              width: isAudioView ? 200 : 500,
              color: Colors.red,
            );
          }),
        ),
      ),
    )
    

    Or you can just remove SingleChildScrollView as it is not needed here

    SizedBox(
      width: 1140,
      child: GridView.count(
        crossAxisCount: isAudioView ? 5 : 3,
        crossAxisSpacing: 16,
        mainAxisSpacing: 16,
        children: List.generate(10, (index) {
          return Container(
            height: 300,
            width: isAudioView ? 200 : 500,
            color: Colors.red,
          );
        }),
      ),
    )
    

    Note: If you are using GridContentView in a column, you have to wrap it in Expanded for this same reason.

    For understanding this issue, I recommend watching the following video as he explains it better: https://www.youtube.com/watch?v=jckqXR5CrPI

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search