如何在Flutter中监听屏幕键盘?

22

我正在制作一款移动应用程序,当键盘出现在屏幕上时,即输入文本字段处于焦点状态时,我希望删除小部件。

我已经尝试使用RawKeyboardListener但似乎不起作用,我的代码如下所示:

new Container(
  child: new RawKeyboardListener(
    focusNode: new FocusNode(),
    onKey: (input) => debugPrint("*****KEY PRESSED"),
    child: new TextField(
      controller: new TextEditingController(),
    ),
  ),
);

请查看此答案:https://dev59.com/W1YM5IYBdhLWcg3wgwXH#63505397 - Abdurahman Popal
请记住,在Dart中不需要使用new - Marwin Lebensky
7个回答

18
您可以使用这个简单的检查:
MediaQuery.of(context).viewInsets.bottom == 0
当此函数返回true时,键盘处于关闭状态,否则为打开状态。请注意要考虑整个屏幕(例如Scaffold)的上下文,而不仅仅是一个小部件。
以下是将此检查集成到您的代码中的方法:
Visibility(
  child: Icon(Icons.add),
  visible: MediaQuery.of(context).viewInsets.bottom == 0,
)

simple and clean - Bilal Şimşek
最佳答案。谢谢。 - gordonturibamwe
2
我已经对Android和iOS设备进行了测试并成功使用。 - Benjamin Menrad
简单清晰的方法。谢谢。 - Sharath B Naik

9
当文本字段被聚焦时,键盘会自动出现。因此,您可以向focusnode添加listner以监听焦点变化并隐藏相应的小部件。
示例:
    void _listener(){
        if(_myNode.hasFocus){
          // keyboard appeared 
        }else{
          // keyboard dismissed
        }
    }

    FocusNode _myNode = new FocusNode()..addListener(_listner);

    TextField _myTextField = new TextField(
            focusNode: _mynNode,
            ...
            ...
        );

    new Container(
        child: _myTextField
    );

21
很遗憾,当键盘被隐藏时这个方法不起作用,似乎文本框没有失去焦点。 - Thomas

3

我使用了名为 keyboard_visibility 的包。

然后,我将我的 TextField 包装在一个实现如下的 KeyboardListener 中:

class KeyboardListener extends StatefulWidget {
  final Widget child;
  final void Function(bool) onChange;
  KeyboardListener({@required this.child, @required this.onChange});
  @override
  _KeyboardListenerState createState() => _KeyboardListenerState();
}

class _KeyboardListenerState extends State<KeyboardListener> {
  int _sId;
  KeyboardVisibilityNotification _kvn;

  @override
  void initState() {
    super.initState();
    _kvn = KeyboardVisibilityNotification();
    _sId = _kvn.addNewListener(
      onChange: widget.onChange,
    );
  }

  @override
  Widget build(BuildContext context) {
    return widget.child;
  }

  @override
  void dispose() {
    _kvn.removeListener(_sId);
    super.dispose();
  }
}

这个包在安卓设备上出现了问题。维护者不会修复它。https://github.com/MisterJimson/flutter_keyboard_visibility/issues/74 - Oliver Dixon

2
您可以使用这个库 keyboard_visibility: ^0.5.6: https://pub.dev/packages/keyboard_visibility 为了执行您的代码,请在 initState() 中插入以下内容: KeyboardVisibilityNotification.addNewListener( onChange: (bool visible) { print(visible); this.setState(() { keyboardIsOpen = visible; }); }, ); 每当键盘打开或关闭时,该库都会调用 onChange 方法,并传递一个布尔值来表示可见性。

1

检查键盘是否打开的条件,您可以使用WidgetsBinding.instance.window.viewInsets.bottom,由Deepak Raj回答。

或者您可以使用: KeyboardVisibilityBuilder

Andrey Gordeev回答。

KeyboardVisibilityBuilder(
    builder: (context, child, isKeyboardVisible) {
      if (isKeyboardVisible) {
        // when keyboard is visible
        return mChild;
      } else {
        // when keyboard is invisible
        return SizedBox.shrink();
      }
      
    },
    child: mChild,
  )

0
import 'dart:async';
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';

class KeyboardHookWidget extends HookWidget {
  const KeyboardHookWidget({super.key});

  @override
  Widget build(BuildContext context) {
    late StreamSubscription<bool> keyboardSubscription;
    ValueNotifier<bool> isVisibleKeyboard = useState(true);
    useEffect(() {
      KeyboardVisibilityController keyboardVisibilityController =
          KeyboardVisibilityController();
      keyboardSubscription =
          keyboardVisibilityController.onChange.listen((bool visible) {
        isVisibleKeyboard.value = visible;
        //isVisibleKeyboard.value 
      });
      return () => keyboardSubscription.cancel();
    }, []);
    
  }
}

-1
一个小部件,每当用户在键盘上按下或释放键时调用回调函数。
RawKeyboardListener 对于监听原始键事件和表示为键的硬件按钮非常有用。通常由游戏和其他使用键盘进行文本输入以外目的的应用程序使用。
对于文本输入,请考虑使用 EditableText,它与屏幕键盘和输入法编辑器(IME)集成。
 const RawKeyboardListener({
Key key,
@required FocusNode focusNode,
@required ValueChanged<RawKeyEvent> onKey,
@required Widget child
})

创建一个小部件,接收原始键盘事件。 对于文本输入,请考虑使用EditableText,它与屏幕键盘和输入法编辑器(IME)集成。 实现
const RawKeyboardListener({
  Key key,
  @required this.focusNode,
  @required this.onKey,
  @required this.child,
}) : assert(focusNode != null),
     assert(child != null),
     super(key: key);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接