简体   繁体   中英

Flutter nested ListView.separated

I'd like to have a ListView of columns that could scroll horizontally and in each of those columns a ListView of rows that could scroll vertically.

Here's the code that I wrote:

@override
Widget build(BuildContext context) {
  return Center(
    child: Column(
      mainAxisAlignment: MainAxisAlignment.start,
      mainAxisSize: MainAxisSize.min,
      children: [
        Text(
          "AppName",
          textAlign: TextAlign.center,
        ),
        Expanded(
          //This is the first ListView, the itemBuilder returns a Column
          child: ListView.separated(
            scrollDirection: Axis.horizontal,
            controller: scrollController,
            itemCount: filesProvider.directories.length,
            itemBuilder: (BuildContext context, int index) {
              return buildColumn(context, index, filesProvider);
            },
            separatorBuilder: (BuildContext context, int index) {
              return SizedBox(
                width: 30,
              );
            },
          ),
        ),
      ],
    ),
  );
}

Column buildColumn(BuildContext context, int index, FilesProvider provider) {
  return Column(
    children: [
      Text(
        "Column "+index,
        textAlign: TextAlign.center,
      ),
      Expanded(
        //This is the second ListView, the itemBuilder returns a Row
        child: ListView.separated(
          scrollDirection: Axis.vertical,
          controller: scrollController,
          itemCount: (provider.dirNames[index].length / colonnePerTipo).round(),
          itemBuilder: (BuildContext context, int rowIndex) {
            return buildRow(context, rowIndex, provider);
          },
          separatorBuilder: (BuildContext context, int rowIndex) {
            return SizedBox(
              width: 10,
            );
          },
        ),
      ),
    ],
  );
}

Row buildRow(BuildContext context, int index, FilesProvider provider) {
  List<Widget> sizedBoxes = [];

  for (int i = 0; i < buttonForRow; i++) {
    sizedBoxes.add(
      SizedBox(
        width: 20,
        child: ElevatedButton(
          child: Text("Button"),
        ),
      ),
    );
  }

  return Row(
    mainAxisAlignment: MainAxisAlignment.spaceEvenly,
    children: sizedBoxes,
  );
}

It seems fine to me but when I run it I receive this error:

======== Exception caught by rendering library =====================================================
The following assertion was thrown during paint():
RenderBox was not laid out: RenderRepaintBoundary#29de6 relayoutBoundary=up2 NEEDS-PAINT
'package:flutter/src/rendering/box.dart':
Failed assertion: line 1929 pos 12: 'hasSize'

I don't understand what the problem could be. Can someone help me?

You are getting this error because you have wrapped your widget in Expanded widget and hence your ListView.separated widgets viewports are getting unbounded height and width. ListView.separated doesn't know how much space to take.

try wrapping both your ListView.separated widgets in SizedBox instead of Expanded to give them height and width constraints

try this code

    @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          mainAxisSize: MainAxisSize.min,
          children: [
            const Text(
              "AppName",
              textAlign: TextAlign.center,
            ),
            SizedBox(
              height: 300,
              //This is the first ListView, the itemBuilder returns a Column
              child: ListView.separated(
                scrollDirection: Axis.horizontal,
                itemCount: 10,
                itemBuilder: (BuildContext context, int index) {
                  return buildColumn(context, index);
                },
                separatorBuilder: (BuildContext context, int index) {
                  return const SizedBox(
                    width: 30,
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }

  Column buildColumn(BuildContext context, int index) {
    return Column(
      children: [
        Text(
          "Column " + index.toString(),
          textAlign: TextAlign.center,
        ),
        SizedBox(
          height: 200,
          width: 180,
          //This is the second ListView, the itemBuilder returns a Row
          child: ListView.separated(
            scrollDirection: Axis.vertical,
            itemCount: 5,
            itemBuilder: (BuildContext context, int rowIndex) {
              return buildRow(context, rowIndex);
            },
            separatorBuilder: (BuildContext context, int rowIndex) {
              return const SizedBox(
                height: 10,
              );
            },
          ),
        ),
      ],
    );
  }

  Row buildRow(BuildContext context, int index) {
    List<Widget> sizedBoxes = [];

    for (int i = 0; i < 3; i++) {
      sizedBoxes.add(
        SizedBox(
          width: 60,
          child: ElevatedButton(
            onPressed: () {  },
            child: const Text("cta"),
          ),
        ),
      );
    }

    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: sizedBoxes,
    );
  }

screenshot

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM