Determine Scroll Widget height

4,063
class _MyHomePageState extends State<MyHomePage> {
  bool showMore = false;
  final scrollController = ScrollController();

  @override
  Widget build(BuildContext context) {
    SchedulerBinding.instance.addPostFrameCallback((_) {
      setState(() {
        showMore = scrollController.position.maxScrollExtent > 0;
      });
    });
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Expanded(
              flex: 9,
              child: SingleChildScrollView(
                controller: scrollController,
                child: SizedBox(height: 650, child: Text('blah')),
              ),
            ),
            if (showMore) Expanded(flex: 1, child: Text('Scroll for more')),
          ],
        ),
      ),
    );
  }
}
Share:
4,063
Vinayakaram Nagarajan
Author by

Vinayakaram Nagarajan

I work as a web-application developer at a university in the Netherlands. My main interests are open source programming languages like Javascript, PHP and MySQL. For my daily job I use CodeIgniter and jQuery. For my pet projects I use Laravel, Dojo and Dart. I also used to use Couchdb and Lotus Notes, but not anymore.

Updated on December 13, 2022

Comments

  • Vinayakaram Nagarajan
    Vinayakaram Nagarajan over 1 year

    I would like to determine if a 'scrollable' widget indeed needs to scroll. I would ultimately like to show something like 'Scroll for more'. How do I achieve this?

    I could use a combination of LayoutBuilder and a ScrollController. However, ScrollController gives me maxScrollExtent and minScrollExtent only after any event - like say for example user trying to scroll

    I would like to know during 'build' so that I can determine to show 'Scroll for more' or not depending on the screen dimensions

    class _MyHomePageState extends State<MyHomePage> {
      int value = 0;
      String text = 'You have pushed the button 0 times\n';
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Expanded(
                  flex: 9,
                  child: SingleChildScrollView(
                    child: Text(text),
                  ),
                ),
                Expanded(
                  flex: 1,
                    child: Text('Scroll for more')),
              ],
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: () {
              setState(() {
                value += 1;
                text = text + 'You have pushed the button $value times \n';
              });
            },
            tooltip: 'Increment',
            child: Icon(Icons.add),
          ), 
        );
      }
    }
    

    I would like to dynamically display

                Text('Scroll for more'),
    
    

    only if the SingleChildScrollView needs to be scrolled to view the entire content. Please note, I am just giving the above code as example.

    In my real case, I have a StreamBuilder inside a SingleChildScrollView and I cannot determine how much of data is going to be flowing in from the stream. I also do not have any button or tap or any gesture to access the controller and setState

    Thanks in advance for any help

  • Vinayakaram Nagarajan
    Vinayakaram Nagarajan over 4 years
    Thanks a lot! This works with the example. However, as I have mentioned my real situation is a StreamBuilder returning the Scrolling Widget. In this case, I get the error "flutter: ScrollController not attached to any scroll views". Any additional help here please
  • Tom Robinson
    Tom Robinson over 4 years
    You'll probably need to do some combo of: 1. The above 2. When you get an update on the stream, check if there's a position attached to the controller, and, if so, then update the state of the "show more" widget
  • Vinayakaram Nagarajan
    Vinayakaram Nagarajan over 4 years
    Great, I checked for hasClients on the controller and it does not give me an error anymore. Thanks again