Flutter:检测键盘打开和关闭[重复]

Posted

技术标签:

【中文标题】Flutter:检测键盘打开和关闭[重复]【英文标题】:Flutter: Detect keyboard open and close [duplicate] 【发布时间】:2018-07-22 20:27:29 【问题描述】:

我的应用程序的最上层有一个BottomNavigationBar。我想检测应用程序/子树中基本上任何地方的键盘打开和关闭,所以只要键盘可见,我就可以显示和隐藏BottomNavigationBar

这是一个普遍问题,可能与BottomNavigationBar 没有直接关系。换句话说,从BottomNavigationBar 中抽象出来:-)

【问题讨论】:

pub.dev/packages/flutter_keyboard_visibility/install 找到这个插件。 【参考方案1】:

要检查键盘可见性,只需检查小部件树中任意位置的viewInsets 属性。 viewInsets.bottom 等于 0 时键盘隐藏。

您可以使用MediaQuery 来检查viewInsets,例如:

MediaQuery.of(context).viewInsets.bottom

【讨论】:

这是一种不好的做法。 ViewInset 并非特定于键盘。我建议使用 platform_channel 直接调用原生 API 来判断键盘是否可见。 @Darky 但这是你能做到的唯一方法。观察窗口大小以推断键盘是否可见,据我所知,没有直接的方法。你可以看看this。如果我错了,请纠正我。 但 ViewInset 不是“isKeyboardVisible”。如果你有一个浮动键盘,它会在 ViewInset 为 0 时可见 没错,但理想情况下isKeyboardVisible = viewInsets.bottom > 200px 或理想情况下不等于零。没有其他方法可以判断键盘是否可见。 实现 WidgetsBindingObserver 尤其是方法 didChangeMetrics 可能是一个解决方案。见article【参考方案2】:

我刚刚创建了一个 Flutter 插件来通知键盘打开和关闭事件。它适用于 androidios

keyboard_visibility


import 'package:keyboard_visibility/keyboard_visibility.dart';

@override
void initState() 
  super.initState();

  KeyboardVisibilityNotification().addNewListener(
    onChange: (bool visible) 
      print(visible);
    ,
  );

【讨论】:

我们应该如何使用这个插件?有什么文件吗? 请参考自述。使用起来非常简单:link 抱歉,我在 pub.dartlang 上找不到包。这太棒了,我发现这是知道键盘是否真的可见的唯一方法(即使您的键盘有浮动键盘) 插件未更新,请转至此分支:github.com/MisterJimson/flutter_keyboard_visibility 这个包不支持NULL SEFETY,所以它是无用的。【参考方案3】:

您可以使用 keyboard_visibility 包来有效地执行此操作。我用过它,它就像一个魅力。

安装

dependencies:
  keyboard_visibility: ^0.5.2

用法

import 'package:keyboard_visibility/keyboard_visibility.dart';

@protected
void initState() 
  super.initState();

  KeyboardVisibilityNotification().addNewListener(
    onChange: (bool visible) 
      print(visible);
    ,
  );

它还支持显示/隐藏等监听器。

Here is the link.

【讨论】:

您的示例应该更清晰,并显示保存订阅 ID,并附带删除调用,否则如果您多次使用屏幕,您将获得多个侦听器。当类超出范围时,侦听器不会自动处理。除此之外,漂亮,干净,易于使用。谢谢! 这个插件会阻止你为发布而构建 我实际使用过它,我已经为发布而构建,甚至多次发布。 此软件包不支持 NULL SAFETY。这现在没用了。【参考方案4】:

您可以使用WidgetsBinding.instance.window.viewInsets.bottom。如果它的值大于0.0,那么键盘是可见的。

    if(WidgetsBinding.instance.window.viewInsets.bottom > 0.0)
    
       // Keyboard is visible.
    
    else
    
       // Keyboard is not visible.
    

【讨论】:

即使键盘处于活动状态或打开状态,它也会返回 0.0 (这真的是预期的语法突出显示吗?看起来很奇怪。可能是“窗口”匹配完全不同的东西(使用不同的编程语言)。)【参考方案5】:

在您的StatefullWidget 中,创建一个变量:

bool _keyboardVisible = false;

然后在build 小部件中初始化该变量;

@override
Widget build(BuildContext context) 
    _keyboardVisible = MediaQuery.of(context).viewInsets.bottom != 0;
    return child;

【讨论】:

【参考方案6】:

您可以使用MediaQuery.of(context).viewInsets.bottom。请看下面的文档。

/// 被系统 UI 完全遮挡的显示部分,/// 通常被设备的键盘遮挡。 /// /// 当一个 移动设备的键盘可见viewInsets.bottom /// 对应于键盘的顶部。 /// /// 这个值是 独立于[填充]:两个值都是 /// 从 [MediaQuery] 小部件边界的边缘。 /// 顶部的边界 [WidgetsApp] 创建的级别 MediaQuery 与 /// 相同 包含应用程序的窗口(通常是移动设备屏幕)。 /// /// 另见: /// /// * [MediaQueryData],它提供了一些 有关此 /// 属性的其他详细信息以及它与 [填充]。 final EdgeInsets viewInsets;

【讨论】:

【参考方案7】:

你可以使用 Flutter keyboard visibility plugin

@override
Widget build(BuildContext context) 
  return KeyboardVisibilityBuilder(
    builder: (context, isKeyboardVisible) 
      return Text(
        'The keyboard is: $isKeyboardVisible ? 'VISIBLE' : 'NOT VISIBLE'',
      );
    
  );

【讨论】:

【参考方案8】:

这是我的解决方案,使用WidgetsBindingObserver观察窗口大小变化,并据此判断键盘是否隐藏。

/// My widget state,it can remove the focus to end editing when the keyboard is hidden.
class MyWidgetState extends State<MyWidget> with WidgetsBindingObserver 
  /// Determine whether the keyboard is hidden.
  Future<bool> get keyboardHidden async 
    // If the embedded value at the bottom of the window is not greater than 0, the keyboard is not displayed.
    final check = () => (WidgetsBinding.instance?.window.viewInsets.bottom ?? 0) <= 0;
    // If the keyboard is displayed, return the result directly.
    if (!check()) return false;
    // If the keyboard is hidden, in order to cope with the misjudgment caused by the keyboard display/hidden animation process, wait for 0.1 seconds and then check again and return the result.
    return await Future.delayed(Duration(milliseconds: 100), () => check());
  

  @override
  void initState() 
    super.initState();
    // Used to obtain the change of the window size to determine whether the keyboard is hidden.
    WidgetsBinding.instance?.addObserver(this);
  

  @override
  void dispose() 
    // stop Observing the window size changes.
    WidgetsBinding.instance?.removeObserver(this);
    super.dispose();
  
  
  @override
  void didChangeMetrics() 
    // When the window insets changes, the method will be called by the system, where we can judge whether the keyboard is hidden.
    // If the keyboard is hidden, unfocus to end editing.
    keyboardHidden.then((value) => value ? FocusManager.instance.primaryFocus?.unfocus() : null);
  

【讨论】:

【参考方案9】:

使用 Flutter 2.0 和 null 安全性,我使用这个包 - 它没有流,纯 Dart,提供有关键盘高度等的附加信息。

flutter_keyboard_size 1.0.0+4

【讨论】:

MediaQuery.of(context).viewInsets.bottom 已经给你键盘高度了吗?【参考方案10】:

我在这里找到了一个更简单的解决方案:

将DesiredBottomWidget放在Stack()Positioned(top: somevalue)中,出现键盘时会隐藏。

例子:

Stack(
    "Somewidget()",
    Positioned(
        top: "somevalue",
        child: "DesiredBottomWidget()"),
),

【讨论】:

【参考方案11】:

我使用了一种解决方法。我在输入中添加了一个 focusNode 并为其添加了一个侦听器。

在此处查看实现add focus listener to input。

【讨论】:

以上是关于Flutter:检测键盘打开和关闭[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何在 React Native 中检测键盘何时打开或关闭

Flutter - 在 AlertDialog 小部件之外点击后关闭系统键盘

防止键盘事件在 Flutter 中冒泡(传播给父母)

在 TextFormField 中检测新行 - Flutter

Flutter Webview 关闭键盘

关闭网页视图后,来自 Youtube 嵌入式视频的音频继续播放 - Flutter