Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to scroll only down direction in flutter?

Tags:

flutter

I have a Pageview scroll which can be scrolled in up and down direction. Can i make it to scroll only downwards once scrolled down cannot go up . I googled but i haven't found anything useful

Update :

class _ScrollDownOnlyState extends State<ScrollDownOnly> {
  bool checkDir = false;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Down scroll"),
      ),
      body: PageView.builder(
        scrollDirection: Axis.vertical,
        physics: checkDir ? const NeverScrollableScrollPhysics() : const AlwaysScrollableScrollPhysics(),
        itemBuilder: (context, index) {
          print("checl $checkDir");
          return GestureDetector(
            onPanUpdate: (details) {
              print(details.delta.dy);
              if (details.delta.dy > 0) {
                setState(() {
                  checkDir = true;
                });
              }
              if (details.delta.dy < 0) {
                // set your var
                setState(() {
                  checkDir = false;
                });
              }
            },
            child: Container(
              margin: EdgeInsets.only(top: 20),
              color: Colors.pink,
              child: Center(
                child: Text(
                  "${index + 1}",
                  style: TextStyle(color: Colors.white, fontSize: 30),
                ),
              ),
            ),
          );
        },
        itemCount: 50,
      ),
    );
  }
}
like image 362
Naveen Avatar asked Jan 28 '26 07:01

Naveen


2 Answers

I was stuck on this for a while myself (the other posted answers did not work for me) so I'm posting my solution 😁

Whenever the user scrolls in the allowed direction, I remove from my list (myItems in the example) the element that's just gone offscreen. In my case, I've configured (not shown) my ListView to snap scrolls to predictable positions, such that any scroll will push exactly one element offscreen at a time (so myItems.removeAt(0) suffices). If you have multiple elements going offscreen at once, you'll need to keep count somehow such that you remove the number that have gone offscreen. Since I also setState after removing from my list, the ListView is updated accordingly.

NotificationListener(
  onNotification: (scroll) {
    if (scroll is UserScrollNotification && scroll.direction == ScrollDirection.reverse) {
       scrolling = true;
    } else if (scroll is UserScrollNotification && scroll.direction == ScrollDirection.forward) {
       scrolling = false;
    }
    if (scrolling && scroll is ScrollEndNotification && scroll.metrics.axisDirection == AxisDirection.right) {
      scrolling = false;
      setState(() {
        myItems.removeAt(0);
      });
    }   
    return true;
  },
  child: ListView(
           key: ObjectKey(myItems),
           children: myItems,
           scrollDirection: Axis.horizontal,
         ),
)

Note that I also use a variable (which I've named scrolling) to track state. This is necessary because attempting to scroll the opposite direction still triggers a ScrollEndNotification in the allowed direction. I set scrolling = true only when the user has initiated a scroll in the allowed direction so that setState is only called upon ScrollEndNotifications under those conditions. More details on how ScrollNotifications work are available here: https://api.flutter.dev/flutter/widgets/ScrollNotification-class.html

Also note that my example does things horizontally, preventing the user from swiping left-to-right to scroll, and allowing the user to scroll by swiping from right-to-left. You can adapt this approach to vertical (up only or down only) by changing the scrollDirection parameter and tweaking the ScrollDirection and AxisDirection terms until you see your desired behavior.

like image 91
mwarrior Avatar answered Jan 30 '26 00:01

mwarrior


You could for example use a var scrollDir and apply it to the PageView

physics: scrollDir ? const  NeverScrollableScrollPhysics() : const AlwaysScrollableScrollPhysics(),

With NeverScrollableScrollPhysics() youre blocking the scroll abillity. With AlwaysScrollableScrollPhysics() you're activating scrolling features.

You would get full control with a GestureDetector detecting up or down scrolling. It could maybe look something like this in total:

PageView(
            children: <Widget>[
              // Add children here
              GestureDetector(
                  onPanUpdate: (details) {
                    if (details.delta.dy > 0) {
                      setState(() {
                        checkDir = true;
                      });
                    }
                    if (details.delta.dy < 0) {
                      // set your var
                      checkDir = false;
                    }
                  },
                  child: Container(child: Text('MY WIDGETS')))
            ],
            physics: checkDir
                ? const NeverScrollableScrollPhysics()
                : const AlwaysScrollableScrollPhysics(),
          )),

Scrollphysics doc: https://api.flutter.dev/flutter/widgets/ScrollPhysics-class.html

GestureDetector doc: https://api.flutter.dev/flutter/widgets/GestureDetector-class.html

like image 38
Marcel Dz Avatar answered Jan 29 '26 22:01

Marcel Dz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!