Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter how to get last PageView scroll direction

Tags:

flutter

I'm trying to get which direction(left or right) user swiped by using PageView. I was able to get direction like so.

Code:

 PageController _controller;

  @override
  void initState() {
    _controller = new PageController()..addListener(_listener);
    super.initState();
  }

  _listener() {
    if (_controller.position.userScrollDirection == ScrollDirection.reverse) {
      print('swiped to right');
    } else {
      print('swiped to left');
    }
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(),
      body: PageView.builder(
          itemCount: 10,
          controller: _controller,
          itemBuilder: (context, index) {
            return new Center(child: Text('item ${++index}'));
          }),
    );
  }

However since it's not getting end of scrolling, print method return this many times. Is there way I can get this after current page switched to next page completely?

flutter: swiped to right
flutter: swiped to right
flutter: swiped to right
flutter: swiped to right
flutter: swiped to right
flutter: swiped to right
flutter: swiped to right
flutter: swiped to right
flutter: swiped to right
flutter: swiped to right
flutter: swiped to right

like image 318
Daibaku Avatar asked Sep 06 '18 11:09

Daibaku


3 Answers

A better solution is as follows, using the PageView widget's built in function.

 PageView(
 onPageChanged: (int page) { 
 // this page variable is the new page and will change before the pageController fully reaches the full, rounded int value
   var swipingRight = page > pageController.page;
   print(swipingRight);
  },
like image 71
ThinkDigital Avatar answered Oct 28 '22 18:10

ThinkDigital


None of the solutions here worked for me, figuring this out was a huge headache.

I ended up using a gesture detector and disabling the PageView gestures entirely.

The NeverScrollableScrollPhysics() is how you disable the PageView's built-in gestures.

class MyPageView extends StatefulWidget {
  @override
  _MyPageViewState createState() => _MyPageViewState();
}

class _MyPageViewState extends State<MyPageView> {
  PageController _pageController;
  Duration pageTurnDuration = Duration(milliseconds: 500);
  Curve pageTurnCurve = Curves.ease;

  @override
  void initState() {
    super.initState();
    // The PageController allows us to instruct the PageView to change pages.
    _pageController = PageController();
  }

  void _goForward() {
    _pageController.nextPage(duration: pageTurnDuration, curve: pageTurnCurve);
  }

  void _goBack() {
    _pageController.previousPage(
        duration: pageTurnDuration, curve: pageTurnCurve);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: GestureDetector(
        // Using the DragEndDetails allows us to only fire once per swipe.
        onHorizontalDragEnd: (dragEndDetails) {
          if (dragEndDetails.primaryVelocity < 0) {
            // Page forwards
            print('Move page forwards');
            _goForward();
          } else if (dragEndDetails.primaryVelocity > 0) {
            // Page backwards
            print('Move page backwards');
            _goBack();
          }
        },
        child: PageView.builder(
            itemCount: 10,
            controller: _pageController,
            // NeverScrollableScrollPhysics disables PageView built-in gestures.
            physics: NeverScrollableScrollPhysics(),
            itemBuilder: (context, index) {
              return new Center(child: Text('item ${++index}'));
            }),
      ),
    );
  }
}
like image 35
Merritt Avatar answered Oct 28 '22 19:10

Merritt


Compare the current _controller.page.round() with the value from the previous listener invocation (store the previous value in the State).

  • If the current value is greater than the previous value, the user swiped to the right.
  • If the current value is lower than the previous value, the user swiped to the left.
like image 5
boformer Avatar answered Oct 28 '22 17:10

boformer