Home > database >  ListView.builder inside PageView inside SingleChildScrollView gets Unbounded Height Error
ListView.builder inside PageView inside SingleChildScrollView gets Unbounded Height Error

Time:12-13

Flutter Doctor :

Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 3.3.9, on Microsoft Windows [Version 10.0.19044.2251], locale en-US)
[√] Android toolchain - develop for Android devices (Android SDK version 33.0.1)
[√] Chrome - develop for the web
[X] Visual Studio - develop for Windows
    X Visual Studio not installed; this is necessary for Windows development.
      Download at https://visualstudio.microsoft.com/downloads/.
      Please install the "Desktop development with C  " workload, including all of its default components
[√] Android Studio (version 2021.3)
[√] VS Code (version 1.74.0)
[√] Connected device (4 available)
[√] HTTP Host Availability

! Doctor found issues in 1 category.

Minimal Reproducible Code :

import 'package:flutter/material.dart';

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

  @override
  State<Temp> createState() => _TempState();
}

class _TempState extends State<Temp> {
  @override
  Widget build(BuildContext context) {
    PageController pageController = PageController(
      initialPage: 0,
    );

    return Scaffold(
      body: Container(
        padding: const EdgeInsets.symmetric(horizontal: 30),
        margin:
            EdgeInsets.only(top: MediaQuery.of(context).viewPadding.top   10),
        child: SingleChildScrollView(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Container(
                  color: Colors.orangeAccent,
                  height: MediaQuery.of(context).size.height * 0.3,
                  width: MediaQuery.of(context).size.width,
                  child: const Center(child: Text('DUMMY BOX 3'))),
              Container(
                  color: Colors.purpleAccent,
                  height: MediaQuery.of(context).size.height * 0.2,
                  width: MediaQuery.of(context).size.width,
                  child: const Center(child: Text('DUMMY BOX 2'))),
              Container(
                color: Colors.lightBlueAccent,
                height: MediaQuery.of(context).size.height * 0.3,
                width: MediaQuery.of(context).size.width,
                child: const Center(
                  child: Text('DUMMY BOX 3'),
                ),
              ),
              const SizedBox(
                height: 40,
              ),
              PageView(
                controller: pageController,
                children: const [
                  DummyListViewContainerWidget(),
                  DummyListViewContainerWidget(),
                  DummyListViewContainerWidget()
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class DummyListViewContainerWidget extends StatelessWidget {
  const DummyListViewContainerWidget({
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ListView.separated(
        // physics: const NeverScrollableScrollPhysics(),
        shrinkWrap: true,
        itemCount: 10,
        padding: const EdgeInsets.only(bottom: 20),
        separatorBuilder: (cxt, index) {
          return const SizedBox(
            height: 10,
          );
        },
        itemBuilder: (cxt, index) {
          return Container(
            height: 50,
            width: MediaQuery.of(context).size.width,
            color: Colors.brown,
            child: Center(child: Text(index.toString())),
          );
        });
  }
}

Expectations : Whole screen is scrollable not just ListView.

Tried Solutions:

  1. Giving column below of SingleChildScrollView to MainAxisSize.min
  2. Giving Height To PageView which is not a solution to my case. giving height to it will only show view of DummyListViewContainerWidget to that height and will cut the rest of it.
  3. Removing SingleChildScrollView From Top and putting in inside PageView.

CodePudding user response:

Try with the CustomScrollView, something like this:

CustomScrollView(
  slivers: [
    SliverList(
      delegate: SliverChildListDelegate([
        Container(
          height: 100,
          color: Colors.blue,
        ),
        Container(
          height: 100,
          color: Colors.black,
        ),
        Container(
          height: 100,
          color: Colors.green,
        ),
        const SizedBox(
          height: 40,
        ),
      ]),
    ),
    SliverFillRemaining(
      hasScrollBody: true,
      child: PageView(
        controller: pageController,
        children: [
          DummyListViewContainerWidget(),
          DummyListViewContainerWidget(),
          DummyListViewContainerWidget(),
        ],
      ),
    ),
  ],
)

CodePudding user response:

I've updated your code to make the whole thing work :

import 'package:flutter/material.dart';

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

  @override
  State<Temp> createState() => _TempState();
}

class _TempState extends State<Temp> {
  @override
  Widget build(BuildContext context) {
    PageController pageController = PageController(
      initialPage: 0,
    );

    return Scaffold(
      body: Container(
        padding: const EdgeInsets.symmetric(horizontal: 30),
        margin:
            EdgeInsets.only(top: MediaQuery.of(context).viewPadding.top   10),
        child: SingleChildScrollView(
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Container(
                  color: Colors.orangeAccent,
                  height: MediaQuery.of(context).size.height * 0.3,
                  width: MediaQuery.of(context).size.width,
                  child: const Center(child: Text('DUMMY BOX 3'))),
              Container(
                  color: Colors.purpleAccent,
                  height: MediaQuery.of(context).size.height * 0.2,
                  width: MediaQuery.of(context).size.width,
                  child: const Center(child: Text('DUMMY BOX 2'))),
              Container(
                color: Colors.lightBlueAccent,
                height: MediaQuery.of(context).size.height * 0.3,
                width: MediaQuery.of(context).size.width,
                child: const Center(
                  child: Text('DUMMY BOX 3'),
                ),
              ),
              const SizedBox(
                height: 40,
              ),
              SizedBox(
                height: MediaQuery.of(context).size.height, //you just needed to add a definite height to your PageView
                child: PageView(
                  controller: pageController,
                  children: const [
                    DummyListViewContainerWidget(),
                    DummyListViewContainerWidget(),
                    DummyListViewContainerWidget()
                  ],
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

class DummyListViewContainerWidget extends StatelessWidget {
  const DummyListViewContainerWidget({
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ListView.separated(
        // physics: const NeverScrollableScrollPhysics(),
        shrinkWrap: true,
        itemCount: 10,
        padding: const EdgeInsets.only(bottom: 20),
        separatorBuilder: (cxt, index) {
          return const SizedBox(
            height: 10,
          );
        },
        itemBuilder: (cxt, index) {
          return Container(
            height: 50,
            width: MediaQuery.of(context).size.width,
            color: Colors.brown,
            child: Center(child: Text(index.toString())),
          );
        });
  }
}

It was pretty much just that PageView which was causing that error handling it made the code work flawlessly.

  • Related