颤动: 检测键盘打开和关闭

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

这是一个普遍的问题,可能与 BottomNavigationBar没有直接关系。换句话说,摘要来自 BottomNavigationBar: -)

84642 次浏览

To check for keyboard visibility, just check for the viewInsets property anywhere in the widget tree. The keyboard is hidden when viewInsets.bottom is equal to zero.

You can check for the viewInsets with MediaQuery like:

MediaQuery.of(context).viewInsets.bottom

I just created a Flutter plugin to notify about keyboard open and close events. It works both on Android and iOS.

keyboard_visibility


import 'package:keyboard_visibility/keyboard_visibility.dart';


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


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

You can use MediaQuery.of(context).viewInsets.bottom. Just look at the documentation below.

/// The parts of the display that are completely obscured by system UI, /// typically by the device's keyboard. /// /// When a mobile device's keyboard is visible viewInsets.bottom /// corresponds to the top of the keyboard. /// /// This value is independent of the [padding]: both values are /// measured from the edges of the [MediaQuery] widget's bounds. The /// bounds of the top level MediaQuery created by [WidgetsApp] are the /// same as the window (often the mobile device screen) that contains the app. ///
/// See also: /// /// * [MediaQueryData], which provides some additional detail about this /// property and how it differs from [padding]. final EdgeInsets viewInsets;

You can use the keyboard_visibility package to do this effectively. I've used it, and it works like a charm.

To install

dependencies:
keyboard_visibility: ^0.5.2

Usage

import 'package:keyboard_visibility/keyboard_visibility.dart';


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


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

It also supports listeners like show/hide.

Here is the link.

You can use WidgetsBinding.instance.window.viewInsets.bottom. If its value is greater than 0.0 then the keyboard is visible.

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

I found an easier solution here:

Put the DesiredBottomWidget in a Stack() with a Positioned(top: somevalue), and it will be hidden when the keyboard appears.

Example:

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

In your StatefullWidget, create a variable:

bool _keyboardVisible = false;

Then initialize that variable in the build widget;

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

You can use Flutter keyboard visibility plugin

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

With Flutter 2.0 and null safety, I use this package - it has no streams, pure Dart, gives additional information about keyboard height, etc.

flutter_keyboard_size 1.0.0+4

Enter image description here

I used a workaround. I added a focusNode to the input and added a listener to that.

See the implementation here add focus listener to input.

This is my solution, which uses WidgetsBindingObserver to observe window size changes, and determine whether the keyboard is hidden based on this.

/// 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);
}
}