🥅

【Flutter】GridViewを使おうとしたら「Cannot hit test a render box with no size.」

2024/04/10に公開

はじめに

Column内でGridViewを用いてElevatedButtonを並べて表示しようとしたら、
「Another exception was thrown: Cannot hit test a render box with no size.」
という例外が発生したので、これを解決することにしました。

環境

Flutter version: 3.16.9
Dart SDK version: 3.2.6

【Emulator】
Android Studio Flamingo
Android Emulator: Android 14

【Editor】
VSCode

原因

以下の記事によると、Column内でListViewを使用すると、ListViewのサイズが定まらず表示できなくなるようです。そのため、GridViewもListViewと同様に描画するサイズが定める必要がありました。(以後、記事内のListViewをGridViewに置き換えて記載する)
https://qiita.com/tabe_unity/items/4c0fa9b167f4d0a7d7c2

実際のコード(主要部のみ抜粋)

  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        ......
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            GridView.count(
              mainAxisSpacing: 20,
              crossAxisSpacing: 30,
              crossAxisCount: 3,
              physics: const NeverScrollableScrollPhysics(),
              children: <Widget>[
                ElevatedButton(
                  onPressed: debugPrint('pressed'),
                  ...
                ),
                ElevatedButton(
                  onPressed: debugPrint('pressed'),
                  ...
                ),
                ElevatedButton(
                  onPressed: debugPrint('pressed'),
                  ...
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }

対処法

上記リンクの中で、3. LimitedBox, SizedBoxを使う という項目が、GridViewを描画する際の最大サイズを指定する場合の対応パターンとして紹介されており、私の作りたいものと一致しているので今回はこれを試してみました。

修正したコード

  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        ......
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            SizedBox(
              height: 200,
              width: 280,
              GridView.count(
                mainAxisSpacing: 20,
                crossAxisSpacing: 30,
                crossAxisCount: 3,
                physics: const NeverScrollableScrollPhysics(),
                children: <Widget>[
                  ElevatedButton(
                    onPressed: debugPrint('pressed'),
                    ...
                  ),
                  ElevatedButton(
                    onPressed: debugPrint('pressed'),
                    ...
                  ),
                  ElevatedButton(
                    onPressed: debugPrint('pressed'),
                    ...
                  ),
                ],
              ),
            ),
          ],
        ),
      ),
    );
  }

結果

無事に表示されるようになりました。

まとめ

今回はFlutterで
「Another exception was thrown: Cannot hit test a render box with no size.」
という例外が発生した原因と、その解決策について調べました!

GridViewは利用可能な領域を全て埋めようとするため、Column内で使用する際はその描画領域を制限してやる必要があるんですね。

参考

【Flutter】Columnの中でListViewを使う時にエラーが出る

Discussion