Flutter アプリ

【Flutter】SingleChildScrollViewとGridView.builderを併用すると、処理が中断しアプリが動作しない。

2023年8月6日

SingleChildScrollViewとGridView.builderを併用すると、処理が中断しアプリが動作しません。

      body:SingleChildScrollView(
        child: FutureBuilder<List<Map<String, dynamic>>>(
              future: dbProvider.getCountCategory("肩"),
              builder: (BuildContext context, AsyncSnapshot<List<Map<String, dynamic>>> snapshot) {
                if (snapshot.connectionState == ConnectionState.waiting) {
                  return CircularProgressIndicator(); // データ取得中はローディング表示
                } else if (snapshot.hasError) {
                  return Text("データの取得に失敗しました"); // エラーハンドリング
                } else {
                  var data = snapshot.data;
                  var datalength = data!.length;
                  return GridView.builder(
                    itemCount: datalength,
                    gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                      crossAxisCount: 2,),
                  itemBuilder: (context, index) {
                    return Card(
                      color: Colors.red,
                    );
                  },
                  );
                }
              },
            ),
      
        ),

本記事では、 そのエラーの原因と対処方法を紹介します。

本記事の想定読者

  • Flutterでアプリを開発している人

開発環境

$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 3.0.5, on Microsoft Windows [Version 10.0.19045.3208], locale ja-JP)
[√] Android toolchain - develop for Android devices (Android SDK version 32.0.0)
[√] Chrome - develop for the web
[√] Visual Studio - develop for Windows (Visual Studio Community 2022 17.1.4)
[√] Android Studio (version 2021.1)
[!] Android Studio (version 4.1)
    X Unable to determine bundled Java version.
[!] Android Studio (version 4.2)
    X Unable to determine bundled Java version.
[√] VS Code (version 1.81.0)
[√] Connected device (4 available)
[√] HTTP Host Availability

! Doctor found issues in 2 categories.

pubspec.yaml

dependencies:
  flutter:
    sdk: flutter


  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.2
  sticky_grouped_list: ^3.1.0
  intl: ^0.18.1
  google_fonts: ^4.0.4
  sqflite: ^2.0.3+1
  numberpicker: ^2.1.2

原因

エラーが出ている理由は、SingleChildScrollView 内に配置されている GridView.builder の中で Card ウィジェットを返しているためです。GridView.builder はスクロール可能なウィジェットであり、その中にスクロール可能なウィジェット(SingleChildScrollView )を配置することは通常推奨されないため、このコードはエラーを引き起こします。

エラーメッセージ "The relevant error-causing widget was SingleChildScrollView" は、エラーの原因となっているウィジェットが SingleChildScrollView であることを示しています。

一般的に、スクロール可能なウィジェット(例: ListView、GridView)の中に、さらに別のスクロール可能なウィジェットを配置すると、スクロールの挙動が予測不能になり、スクロールが正しく機能しない可能性があります。

対処方法

この問題の解決方法は単純で、SingleChildScrollViewを削除する事です。

      body: FutureBuilder<List<Map<String, dynamic>>>(
      future: dbProvider.getCountCategory("肩"),
      builder: (BuildContext context, AsyncSnapshot<List<Map<String, dynamic>>> snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return CircularProgressIndicator(); // データ取得中はローディング表示
        } else if (snapshot.hasError) {
          return Text("データの取得に失敗しました"); // エラーハンドリング
        } else {
          var data = snapshot.data;
          var datalength = data!.length;
          // return Text(datalength.toString());
          return GridView.builder(
            itemCount: datalength,
            gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
              crossAxisCount: 2,),
          itemBuilder: (context, index) {
            return Card(
              color: Colors.red,
            );
          },
          );
        }
      },
            ),

-Flutter, アプリ