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 插件来通知键盘打开和关闭事件。它适用于 android 和 ios。
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:检测键盘打开和关闭[重复]的主要内容,如果未能解决你的问题,请参考以下文章
Flutter - 在 AlertDialog 小部件之外点击后关闭系统键盘