MisterJimson / flutter_keyboard_visibility

Get notified on keyboard visibility changes in your Flutter app
MIT License
408 stars 121 forks source link

Add support for keyboard dismiss on drag #84

Open fabiancrx opened 3 years ago

fabiancrx commented 3 years ago

Using the KeyboardDismissOnTap widget I wanted the keyboard to also be dismissed on drag, like Listview does so I made some changes and came up with this widget:

/// Removes the current focus and hides the keyboard when
/// the user drags or taps this widget.
///
/// Place this widget somewhere near the top of your widget
/// tree and when the user drags or taps outside of a focused widget,
/// the focus will be removed and the keyboard will be hidden.
class KeyboardDismiss extends StatelessWidget {
  final Widget child;
  final bool dismissOnTap;
  final bool dismissOnDrag;

  const KeyboardDismiss({Key? key, required this.child, this.dismissOnTap = true, this.dismissOnDrag = true})
      : super(key: key);

  void _hideKeyboard(BuildContext context) {
    final currentFocus = FocusScope.of(context);

    if (!currentFocus.hasPrimaryFocus && currentFocus.hasFocus) {
      FocusManager.instance.primaryFocus?.unfocus();
    }
  }

  @override
  Widget build(BuildContext context) {
    return NotificationListener<ScrollUpdateNotification>(
      child: GestureDetector(
          onTap: dismissOnTap
              ? () {
                  _hideKeyboard(context);
                }
              : null,
          child: child),
      onNotification: (ScrollUpdateNotification notification) {
        final focusScope = FocusScope.of(context);
        if (dismissOnDrag && notification.dragDetails != null && focusScope.hasFocus) {
          focusScope.unfocus();
        }
        return false;
      },
    );
  }
}

It does the same as KeyboardDismissOnTap but it also dismisses the keyboard on drag. If this may be considered of interest of the package users and maintainers I could make a PR to add this widget to the repo.

MisterJimson commented 3 years ago

Hmm, very interesting. Thanks for the help.

It feels like this should be the default behaviour for KeyboardDismissOnTap, maybe with a boolean flag to disable the drag dismissal. Would love a PR.

fabiancrx commented 3 years ago

Nice, should I maintain the Widget as KeyboardDismissOnTap(bool dismissOnDrag,Widget child) or give it the more generic KeyboardDismiss(bool dismissOnDrag,bool dismissOnTap,Widget child) name as in the gist? My vote would be for the second option as the widget will be more generic but would not want to break versioning/compatibility for such a rather small change

MisterJimson commented 3 years ago

Agreed on not wanting to break. Lets keep the same name.