How to Detect Swipe In Flutter ?

· 6 min read
How to Detect Swipe In Flutter
How to Detect Swipe In Flutter

GestureDetector Widget is a stateless widget that has parameters in its constructor for different touch events. GestureDetector Widget is a widget that detects gestures. In this article, we will go through how to detect swipe in a flutter.

How to Detect Swipe In Flutter?

Firstly, Wrap your widget in GestureDetector and use onPanUpdate like this:

GestureDetector(onPanUpdate: (details) {
  if (details.delta.dx > 0) {
    // swiping in right direction
  }
});

After that, Wrap Widget in GestureDetector and use onHorizontalDragUpdate as shown

GestureDetector(
    onHorizontalDragUpdate: (details) {  
    // Note: Sensitivity is integer used when you don't want to mess up vertical drag
        if (details.delta.dx > sensitivity) {
            // Right Swipe
        } else if(details.delta.dx < -sensitivity){
            //Left Swipe
        }
    }
);

Using a gesture detector with onHorizontalDragEnd it will only fire once per swipe. Therefore, Consider a code snippet like below:

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}'));
            }),
      ),
    );
  }
}

Using SwipeDetector is straightforward. Just wrap it around the widget you want to detect swipes on.

To use the swipe detector class just copy and paste the file code. Or drag and drop the below dart file in your project directory.

Create a swipedetector.dart and copy and paste this code into your file.

import 'package:flutter/material.dart';

class SwipeConfiguration {
  //Vertical swipe configuration options
  double verticalSwipeMaxWidthThreshold = 50.0;
  double verticalSwipeMinDisplacement = 100.0;
  double verticalSwipeMinVelocity = 300.0;

  //Horizontal swipe configuration options
  double horizontalSwipeMaxHeightThreshold = 50.0;
  double horizontalSwipeMinDisplacement = 100.0;
  double horizontalSwipeMinVelocity = 300.0;

  SwipeConfiguration({
    double verticalSwipeMaxWidthThreshold,
    double verticalSwipeMinDisplacement,
    double verticalSwipeMinVelocity,
    double horizontalSwipeMaxHeightThreshold,
    double horizontalSwipeMinDisplacement,
    double horizontalSwipeMinVelocity,
  }) {
    if (verticalSwipeMaxWidthThreshold != null) {
      this.verticalSwipeMaxWidthThreshold = verticalSwipeMaxWidthThreshold;
    }

    if (verticalSwipeMinDisplacement != null) {
      this.verticalSwipeMinDisplacement = verticalSwipeMinDisplacement;
    }

    if (verticalSwipeMinVelocity != null) {
      this.verticalSwipeMinVelocity = verticalSwipeMinVelocity;
    }

    if (horizontalSwipeMaxHeightThreshold != null) {
      this.horizontalSwipeMaxHeightThreshold = horizontalSwipeMaxHeightThreshold;
    }

    if (horizontalSwipeMinDisplacement != null) {
      this.horizontalSwipeMinDisplacement = horizontalSwipeMinDisplacement;
    }

    if (horizontalSwipeMinVelocity != null) {
      this.horizontalSwipeMinVelocity = horizontalSwipeMinVelocity;
    }
  }
}

class SwipeDetector extends StatelessWidget {
  final Widget child;
  final Function() onSwipeUp;
  final Function() onSwipeDown;
  final Function() onSwipeLeft;
  final Function() onSwipeRight;
  final SwipeConfiguration swipeConfiguration;

  SwipeDetector(
      {@required this.child,
      this.onSwipeUp,
      this.onSwipeDown,
      this.onSwipeLeft,
      this.onSwipeRight,
      SwipeConfiguration swipeConfiguration})
      : this.swipeConfiguration = swipeConfiguration == null
            ? SwipeConfiguration()
            : swipeConfiguration;

  @override
  Widget build(BuildContext context) {
    //Vertical drag details
    DragStartDetails startVerticalDragDetails;
    DragUpdateDetails updateVerticalDragDetails;

    //Horizontal drag details
    DragStartDetails startHorizontalDragDetails;
    DragUpdateDetails updateHorizontalDragDetails;

    return GestureDetector(
      child: child,
      onVerticalDragStart: (dragDetails) {
        startVerticalDragDetails = dragDetails;
      },
      onVerticalDragUpdate: (dragDetails) {
        updateVerticalDragDetails = dragDetails;
      },
      onVerticalDragEnd: (endDetails) {
        double dx = updateVerticalDragDetails.globalPosition.dx -
            startVerticalDragDetails.globalPosition.dx;
        double dy = updateVerticalDragDetails.globalPosition.dy -
            startVerticalDragDetails.globalPosition.dy;
        double velocity = endDetails.primaryVelocity;

        //Convert values to be positive
        if (dx < 0) dx = -dx;
        if (dy < 0) dy = -dy;
        double positiveVelocity = velocity < 0 ? -velocity : velocity;

        if (dx > swipeConfiguration.verticalSwipeMaxWidthThreshold) return;
        if (dy < swipeConfiguration.verticalSwipeMinDisplacement) return;
        if (positiveVelocity < swipeConfiguration.verticalSwipeMinVelocity)
          return;

        if (velocity < 0) {
          //Swipe Up
          if (onSwipeUp != null) {
            onSwipeUp();
          }
        } else {
          //Swipe Down
          if (onSwipeDown != null) {
            onSwipeDown();
          }
        }
      },
      onHorizontalDragStart: (dragDetails) {
        startHorizontalDragDetails = dragDetails;
      },
      onHorizontalDragUpdate: (dragDetails) {
        updateHorizontalDragDetails = dragDetails;
      },
      onHorizontalDragEnd: (endDetails) {
        double dx = updateHorizontalDragDetails.globalPosition.dx -
            startHorizontalDragDetails.globalPosition.dx;
        double dy = updateHorizontalDragDetails.globalPosition.dy -
            startHorizontalDragDetails.globalPosition.dy;
        double velocity = endDetails.primaryVelocity;

        if (dx < 0) dx = -dx;
        if (dy < 0) dy = -dy;
        double positiveVelocity = velocity < 0 ? -velocity : velocity;

        if (dx < swipeConfiguration.horizontalSwipeMinDisplacement) return;
        if (dy > swipeConfiguration.horizontalSwipeMaxHeightThreshold) return;
        if (positiveVelocity < swipeConfiguration.horizontalSwipeMinVelocity)
          return;

        if (velocity < 0) {
          //Swipe Up
          if (onSwipeLeft != null) {
            onSwipeLeft();
          }
        } else {
          //Swipe Down
          if (onSwipeRight != null) {
            onSwipeRight();
          }
        }
      },
    );
  }
}

Therefore use it like this

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: SwipeDetector(
          child: Container(height: 200, width: 300), //Your Widget Tree here
          onSwipeUp: () {
            print("Swipe Up");
          },
          onSwipeDown: () {
           print("Swipe Down");
          },
          onSwipeLeft: () {
            print("Swipe Left");
          },
          onSwipeRight: () {
            print("Swipe Right");
          },
        ),
      ),
    );
  }

You can also try the below way:

GestureDetector(
    onHorizontalDragEnd: (DragEndDetails details) {
      if (details.primaryVelocity > 0) {
        // User swiped Left
      } else if (details.primaryVelocity < 0) {
        // User swiped Right
      }
    }
);

Conclusion:

Thanks for being with us !!!

In this article, we have been through how to detect swipes in a flutter.

So, Keep Learning !!! Keep Fluttering !!!

Flutter Agency is our portal Platform dedicated to Flutter Technology and Flutter Developers. The portal is full of cool resources from Flutter like Flutter Widget GuideFlutter ProjectsCode libs and etc.

Flutter Agency is one of the most popular online portals dedicated to Flutter Technology. Moreover, daily thousands of unique visitors come to this portal to enhance their knowledge of Flutter.

Leave a Reply