Home > Back-end >  ListView.builder disappears inside ListView
ListView.builder disappears inside ListView

Time:02-24

Listiew( children: [ ....., ListView.builder() ]) My widget structure is something like this..

but my ListView builder items disappears

CodePudding user response:

Didnot quite got what you want. This is what I suggest according my understanding.

class MyWidget extends StatefulWidget {
  const MyWidget({Key? key}) : super(key: key);

  @override
  State<MyWidget> createState() => MyWidgetState();
}

class MyWidgetState extends State<MyWidget> {
  var list1 = [
    "JhI2",
    "ddfs",
    "asdf",
    "asdfsghf",
    "sdafg",
    "asdf",
    "asdfsd",
    "dsfbg",
    "sdafsgb",
    "Asder3e",
    "asdfewgrbdvc",
    "afdscvx"
  ];
  var list2 = [3454, 3545, 35, 123, 1234, 124334, 213423, 2454, 3565];
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text("Check")),
        body: ListView(children: [
          Text("zcvbn".toString()),
          TextField(),
          ListView.builder(
              itemCount: list2.length,
              shrinkWrap: true,
              itemBuilder: (ctx, i) {
                return Text(list2[i].toString());
              }),
          TextField(),
          Text("zcvbn".toString()),
          TextField(),
          Text("zcvbn".toString()),
        ]));
  

}
}

CodePudding user response:

This happens because the parent ListView doesn't know how many items child ListView has which causes unbounded height error.

Setting shrinkWrap to true in child ListView will fix your problem. This way the child ListView will be shrinked by evaluating all of its children upfront and treated as a single widget. Although its very costly operation.

Costly solution:

Scaffold(
    appBar: AppBar(
      title: const Text("Listview inside a Listview"),
    ),
    body: ListView.builder(
        itemCount: 5,
        itemBuilder: (ctx, index) {
          Color randomColorforInnerlist = randomColor();
          return ListView.builder(
              itemCount: 5,
              shrinkWrap: true,
              itemBuilder: (ctx, index) {
                return Container(
                  height: 25,
                  color: randomColorforInnerlist,
                  margin: const EdgeInsets.all(8),
                  child: Center(child: Text((index   1).toString())),
                );
              });
        }));

Cost effective solution would be build SliverList and render that inside CustomScrollView, like this:

Optimized Solution:

List<SliverList> outerLists = [];

  void initState() {
    super.initState();
    for (int i = 0; i < 4; i  ) {
      final _innerList = [];
      Color colorForInnerList = randomColor();
      for (int j = 0; j < 5; j  ) {
        _innerList.add(Container(
          height: 25,
          color: colorForInnerList,
          margin: const EdgeInsets.all(8),
          child: Center(child: Text((j   1).toString())),
        ));
      }
      outerLists.add(
        SliverList(
          delegate: SliverChildBuilderDelegate(
                (BuildContext context, int index) => _innerList[index],
            childCount: _innerList.length,
          ),
        ),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text("Listview inside a Listview"),
        ),
        body: CustomScrollView(slivers: outerLists),
        );
  }

  Color randomColor() =>
      Color((math.Random().nextDouble() * 0xFFFFFF).toInt()).withOpacity(1.0);
  • Related