Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

StackOverflow Point

StackOverflow Point Navigation

  • Web Stories
  • Badges
  • Tags
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Web Stories
  • Badges
  • Tags
Home/ Questions/Q 218509
Next
Alex Hales
  • 0
Alex HalesTeacher
Asked: July 14, 20222022-07-14T18:50:46+00:00 2022-07-14T18:50:46+00:00In: Dart, Flutter, flutter-layout

flutter – Vertical viewport was given unbounded height

  • 0

[ad_1]

GridView / ListView grow until constraints (limits) stop this expansion & then scroll to view items beyond that size.

But Column lays out its children without any constraints, completely ignoring its own size and screen size. There is infinite space inside of Column.

Viewport was given unbounded height exception occurs because Grid/ListView expands to infinity inside a Column.

Flexible/Expanded exist to give Column children constraints based Column's size. (These two widgets cannot be used anywhere else, except inside Row and Column.)

Inside a Flexible/Expanded widget in Column, Grid/ListView only uses remaining space not taken by other, non-flexible widgets, which get laid out first. (See bottom for layout phases info.)

Using shrinkWrap: true on ListView inside a Column isn’t really helpful as:

  • ListView no longer scrolls
  • ListView can still overflow

A ListView tall enough to show all of its items, will not scroll. Arguably defeats the purpose of using a ScrollView widget (parent class of ListView).

In Column layout phase 1 (see bottom for explanation of layout phases), ListView can be any height it wants (there are no constraints).
A ListView with shrinkWrap:true will grow in height to show all its items.
With enough items, a shrinkWrapped ListView will grow & grow (it never scrolls) to overflow whatever Column is inside, be it screen or other tighter constraint.

Shouldn’t shrinkWrap just make ListView only as big as its items OR remaining space (up to screen height), and then scroll?

That would make intuitive sense, but inside a Column in phase 1 layout is done in unbounded space.

So, remaining space is unlimited/infinite. A max height is never reached. shrinkWrap:true just keeps growing Column height as items are added until overflowing the screen (or other smaller constraint).

Example shrinkWrap:true Overflow

Here’s an example of adding items to a shrinkwrapped ListView in a Column until its height is taller than the screen, creating an overflow warning area:

(just keep pressing the + sign Floating Action Button)

import 'package:flutter/material.dart';

class ColumnListViewPage extends StatefulWidget {
  @override
  _ColumnListViewPageState createState() => _ColumnListViewPageState();
}

class _ColumnListViewPageState extends State<ColumnListViewPage> {
  int _count = 0;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Column & ListView'),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () {
          setState(() {
            _count++;
          });
        },
      ),
      body: SafeArea(
        child: Container(
          decoration: BoxDecoration(
            border: Border.all(color: Colors.red)
          ),
          /// // without center, Column will be as narrow as possible
          alignment: Alignment.center,
          /// Column is forced (constrained) to match screen dimension,
          child: Column(
            children: [
              Text('Inner (Nested) Column'),
              ListView.separated( // ← should be wrapped in Expanded
                itemCount: _count,
                separatorBuilder: (context, index) => const Divider(),
                itemBuilder: (context, index) => Padding(
                  padding: const EdgeInsets.symmetric(vertical: 38.0),
                  child: Text('Row $index'),
                ),
                shrinkWrap: true, // should be removed
              )
            ],
          ),
        ),
      ),
    );
  }
}
For GridView/ListView in a Column, wrapping within Expanded or Flexible is likely the safest solution.

Expanded / Flexible

Expanded and Flexible can only be used inside Column (and its siblings like Row, etc.).

They must be used as immediate children of Column. We can’t “nest” Expanded/Flexible in SizedBox or other widgets. Only directly under Column as immediate children.

Inside Column, placing ListView/GridView in Expanded or Flexible ensures it will use only available space, rather than infinite space.

Column
→ Expanded
  → ListView

ListView/GridView inside Expanded/Flexible in a Column doesn’t need shrinkWrap because it is constrained (given a max. height) by the Expanded/Flexible widget. So when that constrained/defined height is used up, ListView/GridView will stop growing & begin scrolling.


Column lays out children in 2 phases:

  • 1st without constraints (unbounded space)
  • 2nd with remaining space based on Column's parent

Phase 1

Any Column child not inside Flexible or Expanded will be laid out in phase 1, in infinite, limitless space completely ignoring screen size.

Widgets that need a vertical boundary/constraint to limit their growth (e.g. ListView) will cause a Vertical viewport was given unbounded height exception in phase 1 as there are no vertical bounds in unbounded space.

Most widgets have intrinsic size. Text for example, is only as high as its content & font size/style. It doesn’t try to grow to fill a space. Defined-height widgets play well in Phase 1 of Column layout.

Phase 2

Any widget that grows to fill bounds, should be put in a Flexible or Expanded for Phase 2 layout.

Phase 2 calculates Column's remaining space from its parent constraints minus space used in Phase 1. This remaining space is provided to Phase 2 children as constraints.

ListView for example, will only grow to use remaining space & stop, avoiding viewport exceptions.

More info on Column layout algorithm and how Expanded works within it.

[ad_2]

  • 0 0 Answers
  • 2 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report
Leave an answer

Leave an answer
Cancel reply

Browse

Sidebar

Ask A Question

Related Questions

  • xcode - Can you build dynamic libraries for iOS and ...

    • 0 Answers
  • bash - How to check if a process id (PID) ...

    • 2 Answers
  • database - Oracle: Changing VARCHAR2 column to CLOB

    • 4 Answers
  • What's the difference between HEAD, working tree and index, in ...

    • 3 Answers
  • Amazon EC2 Free tier - how many instances can I ...

    • 0 Answers

Stats

  • Questions : 43k

Subscribe

Login

Forgot Password?

Footer

Follow

© 2022 Stackoverflow Point. All Rights Reserved.

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.