Determine Scroll Widget height
Asked Answered
C

1

3

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

Circumferential answered 2/9, 2019 at 20:32 Comment(0)
I
6
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')),
          ],
        ),
      ),
    );
  }
}
Irreligion answered 2/9, 2019 at 22:19 Comment(3)
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 pleaseCircumferential
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" widgetIrreligion
Great, I checked for hasClients on the controller and it does not give me an error anymore. Thanks againCircumferential

© 2022 - 2024 — McMap. All rights reserved.