Flutter: Dismissing a dialog by swiping

Viewed 770

I have created this image viewer using dialog and I need to implement swipe to exist (dragging top or down) to perform Navigator.of(context).pop()

Here is my code that I need to implement swipe within it.

showGeneralDialog(
  context: context,
  barrierColor: Colors.grey.shade900
      .withOpacity(0.95), // Background color
  barrierDismissible: false,
  barrierLabel: 'Dialog',
  transitionDuration: Duration(
      milliseconds:
          400), 
  pageBuilder: (_, __, ___) {
    // Makes widget fullscreen
    return SafeArea(
      child: SizedBox.expand(
        child: Column(
          children: <Widget>[
          
          ],
        ),
      ),
    );
  },
);

enter image description here

1 Answers

You can wrap the SafeArea inside the dialog with a GestureDetector and use its onVerticalDragUpdate.

I also wrapped the Column with a transparent Container to make the GestureDetector work.

showGeneralDialog(
  context: context,
  barrierColor: Colors.grey.shade900
  .withOpacity(0.95), // Background color
  barrierDismissible: false,
  barrierLabel: 'Dialog',
  transitionDuration: Duration(milliseconds: 400),
  pageBuilder: (context, __, ___) {
    // Makes widget fullscreen
    return GestureDetector(
      onVerticalDragUpdate: (details) {
        int sensitivity = 10;
        if (details.delta.dy > sensitivity ||
            details.delta.dy < -sensitivity) {
          Navigator.of(context).pop();
        }
      },
      child: SafeArea(
        child: SizedBox.expand(
          child: Container(
            color: Colors.transparent,
            child: Column(
              children: [],
            ),
          ),
        ),
      ),
    );
  },
);

To implement the swipe to dismiss behavior, you can use a Dismissible instead of the GestureDetector:

showGeneralDialog(
  context: context,
  barrierColor: Colors.grey.shade900
  .withOpacity(0.95), // Background color
  barrierDismissible: false,
  barrierLabel: 'Dialog',
  transitionDuration: Duration(milliseconds: 400),
  pageBuilder: (context, __, ___) {
    // Makes widget fullscreen
    return Dismissible(
      direction: DismissDirection.vertical,
      onDismissed: (_) {
        Navigator.of(context).pop();
      },
      key: Key("key"),
      child: SafeArea(
        child: SizedBox.expand(
          child: Container(
            color: Colors.transparent,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Container(
                  color: Colors.white,
                  height: 300,
                )
              ],
            ),
          ),
        ),
      ),
    );
  },
);
Related