简体   繁体   English

在 Flutter 应用程序中通过向后滑动手势关闭键盘

[英]Dismiss keyboard on swipe back gesture in Flutter app

I am trying to dismiss the keyboard when the user swipes from the edge to pop route.当用户从边缘滑动到弹出路径时,我试图关闭键盘。

Currently the keyboard doesn't dismiss until the route is completely gone popped, messing up some of the other pages layout until it dismisses目前键盘在路由完全消失之前不会关闭,直到它关闭才会弄乱其他一些页面布局

I did try to use a WillPopScope to determine when the user was going to pop the route, but unfortunately this disables the swipe to pop functionality from iOS or the CupertinoPageRoute .我确实尝试使用WillPopScope来确定用户何时要弹出路由,但不幸的是,这禁用了 iOS 或CupertinoPageRoute的滑动弹出功能。

I just want to find out if there's anyway I can determine when the user swipes from the edge to pop or taps the back button on the appBar and dismiss the keyboard as they do so.我只是想知道是否有任何方法可以确定用户何时从边缘滑动以弹出或点击 appBar 上的后退按钮并在他们这样做时关闭键盘。

If possible, I am trying to dismiss keyboard as soon as they start swiping to pop, as it happens in many apps.如果可能,我会尝试在键盘开始滑动弹出时立即关闭键盘,就像许多应用程序中发生的那样。

I am attaching attaching a gif showing the effect I'm trying to achieve.我附上了一个 gif,显示了我想要达到的效果。

滑动弹出隐藏键盘

You need to create a custom class extending NavigatorObserver , and pass an instance of it to the navigatorObservers property of your MaterialApp or CupertinoApp .您需要创建一个扩展NavigatorObserver的自定义类,并将其实例传递给MaterialAppCupertinoAppnavigatorObservers属性。

Within that custom class, you can override didStartUserGesture and didStopUserGesture , which will be called when the swipe gesture starts/ends.在该自定义类中,您可以覆盖didStartUserGesturedidStopUserGesture ,它们将在滑动手势开始/结束时调用。 This should allow you to achieve the behavior you are looking for.这应该允许您实现您正在寻找的行为。 Note that didStartUserGesture indicates the current route as well as the previous route, based on which you could add logic to determine whether the keyboard should be dismissed or not.请注意, didStartUserGesture指示当前路由以及上一个路由,您可以根据此添加逻辑来确定是否应关闭键盘。

As suggested by Ovidiu正如奥维迪乌所建议的

class DismissKeyboardNavigationObserver extends NavigatorObserver {
  @override
  void didStartUserGesture(Route route, Route previousRoute) {
    SystemChannels.textInput.invokeMethod('TextInput.hide');
    super.didStartUserGesture(route, previousRoute);
  }
}

and in your Material App并在您的 Material App 中

MaterialApp(
  navigatorObservers: [DismissKeyboardNavigationObserver()],
)

This should come naturally and you shouldn't be directly concerned with that because actually, when you pop a route with the keyboard on, it should dismiss properly.这应该是自然而然的,您不应该直接关心它,因为实际上,当您在键盘打开的情况下弹出路由时,它应该正确地关闭。

However, if you want to detect when the user starts swiping and dismiss the keyboard along with it and then pop the current route, you can easily achieve it by wrapping your screen widget with a GestureDetector like so:但是,如果您想检测用户何时开始滑动并关闭键盘,然后弹出当前路线,您可以通过使用GestureDetector包裹您的屏幕小部件轻松实现它,如下所示:

 Widget build(BuildContext context) {
    double dragStart = 0.0;
    return GestureDetector(
      onHorizontalDragStart: (details) => dragStart = details.globalPosition.dx,
      onHorizontalDragUpdate: (details) {
        final double screenWidth = MediaQuery.of(context).size.width;

        // Here I considered a back swipe only when the user swipes until half of the screen width, but you can tweak it to your needs.
        if (dragStart <= screenWidth * 0.05 && details.globalPosition.dx >= screenWidth) {
          FocusScope.of(context).unfocus();
        }
       child: // Your other widgets...
      },

this is something i wrote to handle this issue.这是我写的东西来处理这个问题。 doesnt use any external packages, you would just wrap your content in the main function at the top.不使用任何外部包,您只需将内容包装在顶部的主要功能中。

 Widget swipeOffKeyboard(BuildContext context, {Widget? child}) { return Listener( onPointerMove: (PointerMoveEvent pointer) { disKeyboard(pointer, context); }, child: child, // your content should go here ); } void disKeyboard(PointerMoveEvent pointer, BuildContext context) { double insets = MediaQuery.of(context).viewInsets.bottom; double screenHeight = MediaQuery.of(context).size.height; double position = pointer.position.dy; double keyboardHeight = screenHeight - insets; if (position > keyboardHeight && insets > 0) FocusManager.instance.primaryFocus?.unfocus(); }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM