【2022年最新】動的なListViewを入れ子(Nested)にして表示する方法〔ListView.builder〕

Flutter
 

実現したいこと

ListViewを入れ子で定義して、動的に画面に表示できるようにしたい

以下はイメージムービー。

実装方法

final List<String> weekly_todo = <String>['one', 'two', 'three'];
final List<String> schedule = <String>['202201', '202202', '202203'];
final List<Color> item_color = <Color>[Colors.amber,Colors.blueAccent,Colors.blueGrey,Colors.purpleAccent,];

class TodoListPage extends StatelessWidget {
  const TodoListPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView.builder( 
        itemBuilder: ((BuildContext context, int index) {
          return Padding(
            padding: const EdgeInsets.symmetric(
              vertical: 8.0,
            ),
            child: Container(
              color: item_color[index],
              child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Container(
                      child: Text(schedule[index]),
                      alignment: Alignment.centerLeft,
                    ),
                    ListView.builder(
                      shrinkWrap: true,
                      physics: NeverScrollableScrollPhysics(),
                      itemBuilder: ((BuildContext context, int index) {
                        return Container(
                          height: 60,
                          child: Card(
                            child: ListTile(
                              title: Text(weekly_todo[index]),
                              leading: Icon(
                                IconData(0xef53, fontFamily: 'MaterialIcons'),
                                size: 40.0,
                              ),
                            ),
                          ),
                        );
                      }),
                      itemCount: weekly_todo.length,
                    ),
                    // ),
                  ],
                ),
              ),
            ),
          );
        }),
        itemCount: schedule.length,
      ),
    );
  }
}

ListView.builderで入れ子

親のListView.builderにて定義されたitemBuilderの中にListView.builderを定義することで、ソースにて入れ子で定義することができる。

ただ、このままでは親の高さの定義がNullになってしまうため、以下のような『高さを定義してください』と言ったエラーが出力される。

════════ Exception caught by rendering library ═════════════════════════════════
RenderBox was not laid out: RenderViewport#6a9fd NEEDS-PAINT
'package:flutter/src/rendering/box.dart':
Failed assertion: line 2001 pos 12: 'hasSize'

そこで次の項でエラーを解決する。

shrinkWrapで親のListViewの高さを動的に指定

『shrinkWrap: true』を定義することで親スクロールビューの最大サイズまで引き伸ばすことができる。

故に高さがNullと言われてエラーが出力されていた箇所が解決する。

ここにて『physics: NeverScrollableScrollPhysics()』も追加で定義してあげることで、子スクロールを制限する。

今のままでは親も子もスクロールされてしまうので、上記を定義することで親のスクロールのみとしている。

コメント

タイトルとURLをコピーしました