【Flutter】Vertical viewport was given unbounded height.(エラー対処法)


やりたいこと

下記のように
①見出しText「Columnの先頭」 のしたに、
②GridViewで2列でWidget(ボタン)をスクロール可で配置したい。

エラー発生

普通に考えると、Columnで囲って、、、と考えると思います。
そして発生したエラーがこちら

実際のコード

error.dart
return Container(
    child: Column(
  children: [
    Text('Column の先頭'),
    GridView.builder(
        padding: EdgeInsets.only(bottom: 70),
        gridDelegate:
            SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 2,
          childAspectRatio: 1.5,
        ),
        itemCount: snapshot.data[type].length,
        itemBuilder: (context, index) {
          return playIcon(
              soundData: snapshot.data[type][index],
              type: type);
        })
  ],
));

発生したエラー

════════ Exception caught by rendering library ═════════════════════════════════
The following assertion was thrown during performResize():
Vertical viewport was given unbounded height.

Viewports expand in the scrolling direction to fill their container. In this case, a vertical viewport was given an unlimited amount of vertical space in which to expand. This situation typically happens when a scrollable widget is nested inside another scrollable widget.

If this widget is always nested in a scrollable widget there is no need to use a viewport because there will always be enough vertical space for the children. In this case, consider using a Column instead. Otherwise, consider using the "shrinkWrap" property (or a ShrinkWrappingViewport) to size the height of the viewport to the sum of the heights of its children.

The relevant error-causing widget was
GridView
lib/…/components/soundsList.dart:27
When the exception was thrown, this was the stack
#0      RenderViewport.computeDryLayout.<anonymous closure>
package:flutter/…/rendering/viewport.dart:1365
#1      RenderViewport.computeDryLayout
package:flutter/…/rendering/viewport.dart:1426
#2      RenderBox.performResize
package:flutter/…/rendering/box.dart:2342
#3      RenderObject.layout
package:flutter/…/rendering/object.dart:1763
#4      RenderProxyBoxMixin.performLayout
package:flutter/…/rendering/proxy_box.dart:118
...
The following RenderObject was being processed when the exception was fired: RenderViewport#46b81 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
RenderObject: RenderViewport#46b81 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
    needs compositing
    parentData: <none> (can use size)
    constraints: BoxConstraints(0.0<=w<=398.0, 0.0<=h<=Infinity)
    size: MISSING
    axisDirection: down
    crossAxisDirection: right
    offset: ScrollPositionWithSingleContext#3701e(offset: 0.0, range: null..null, viewport: null, ScrollableState, AlwaysScrollableScrollPhysics -> BouncingScrollPhysics -> RangeMaintainingScrollPhysics, IdleScrollActivity#fe1d6, ScrollDirection.idle)
    anchor: 0.0
    center child: RenderSliverPadding#d4e6a NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
        parentData: paintOffset=Offset(0.0, 0.0)
        constraints: MISSING
        geometry: null
        padding: EdgeInsets(0.0, 0.0, 0.0, 70.0)
        textDirection: ltr
        child: RenderSliverGrid#22183 NEEDS-LAYOUT NEEDS-PAINT
            parentData: paintOffset=Offset(0.0, 0.0)
            constraints: MISSING
            geometry: null
            no children current live
════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════
RenderBox was not laid out: RenderViewport#46b81 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1940 pos 12: 'hasSize'

The relevant error-causing widget was
GridView
lib/…/components/soundsList.dart:27
════════════════════════════════════════════════════════════════════════════════

対処法

Expandedで囲む

Expandedとは?

ExpandedというWidgetは、RowやColumnの子Widget間の隙間を目一杯埋めたいときに使います。
下記にわかりやすくまとめてくれている方がいらっしゃいました。
https://qiita.com/nannany_tis/items/d4114f615e4d53964121

無事エラーが解消されたコード

success.dart
return Container(
    child: Column(
  children: [
    Text('Column の先頭', style:TextStyle(fontSize: 40)),
    Expanded(
    child: GridView.builder(
        padding: EdgeInsets.only(bottom: 70),
        gridDelegate:
            SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 2,
          childAspectRatio: 1.5,
        ),
        itemCount: snapshot.data[type].length,
        itemBuilder: (context, index) {
          return playIcon(
              soundData: snapshot.data[type][index],
              type: type);
        })
    ),
  ],
));

環境

Flutter 1.26.0-17.3.pre
Dart 2.12.0

参考記事