skip to Main Content

On my screen I need to display a ListView inside an other ListView. The screen can be summarized like this:

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Isolate FutureBuilder Example'),
        ),
        body: Column(
          children: [
            Text("Header"),
            SizedBox(height: 16),
            Text("Filters"),
            SizedBox(height: 32),
            Expanded(
              child: ListView.builder(
                itemCount: 3,
                itemBuilder: (context, index) {
                  return Column(
                    children: [
                      Text("List $index"),
                      SizedBox(height: 32),
                      ListView.builder(
                          shrinkWrap: true,
                          physics: const ClampingScrollPhysics(),
                          itemCount: 50,
                          itemBuilder: (context, index) {
                            print("building $index");
                            return Text("$index");
                          })
                    ],
                  );
                },
              ),
            )
          ],
        ));
  }

If you try it, you will se that all the 200 items of the inner ListView.builder are built immediately, causing an UI jam in my main app since I have many more and more complex items.

How can I prevent this and keep the ListView behavior that builds only the visible items? I read that shrinkWrap: true can be the cause, but if I set it to false I have an error Vertical viewport was given unbounded height. and I am not able to fix it

2

Answers


  1. try to replace your code with this

    i think you don’t need a listview inside a listview

        @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(
              title: Text('Isolate FutureBuilder Example'),
            ),
            body: Column(
              children: [
                Text("Header"),
                SizedBox(height: 16),
                Text("Filters"),
                SizedBox(height: 32),
                Text("List 1"),
                SizedBox(height: 32),
                Expanded(
                  child: ListView(
                    children: [
                      Container(
                        height: MediaQuery.of(context).size.height * 0.5, // Adjust height as needed
                        child: ListView.builder(
                          physics: const ClampingScrollPhysics(),
                          itemCount: 200,
                          itemBuilder: (context, index) {
                            print("building $index");
                            return Text("$index");
                          },
                        ),
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ),
        );
      }
    
    Login or Signup to reply.
  2. You can try this code

    return Scaffold(
          appBar: AppBar(
            title: const Text('Isolate FutureBuilder Example'),
          ),
          body: CustomScrollView(
            physics: const ClampingScrollPhysics(),
            slivers: [
              const SliverAppBar(
                title: Text('Isolate FutureBuilder Example'),
              ),
              const SliverToBoxAdapter(
                child: Column(
                  children: [
                    Text("Header"),
                    SizedBox(height: 16),
                    Text("Filters"),
                    SizedBox(height: 32),
                  ],
                ),
              ),
              ...Iterable.generate(3, (index) {
                return [
                  SliverToBoxAdapter(
                    child: Column(
                      children: [
                        Text("List $index"),
                        const SizedBox(height: 32),
                      ],
                    ),
                  ),
                  SliverList.builder(
                    itemBuilder: (context, index) {
                      print("building $index");
                      return Text("$index");
                    },
                    itemCount: 50,
                  )
                ];
              }).toList().expand((element) => element).toList()
            ],
          ),
        );
      }
    

    here the nested list view is broken into flat listview using CustomScrollView and Slivers.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search