颤动键盘听隐藏和显示

时间:2018-01-03 21:13:15

标签: flutter

如何判断键盘是否显示或隐藏?

我试过这个例子 How to listen to keyboard on screen Flutter?

 void _listener(){
    if(_myNode.hasFocus){
      // keyboard appeared 
    }else{
      // keyboard dismissed
    }
}

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

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

但不幸的是它不起作用。有什么想法可以听取键盘的变化吗?

当我按下" Done"它似乎有效。在键盘上。但是,如果我按下我的手机,它就不会去键盘被解雇"因为焦点仍然存在..有任何帮助吗?

5 个答案:

答案 0 :(得分:3)

KeyboardVisibilityBuilder

使用WidgetsBindingObserver mixin可以监听键盘的显示/隐藏事件。我准备了KeyboardVisibilityBuilder小部件来为您处理行为。用法与AnimatedBuilder非常相似:

return KeyboardVisibilityBuilder(
  builder: (context, child, isKeyboardVisible) {
    if (isKeyboardVisible) {
      // build layout for visible keyboard
    } else {
      // build layout for invisible keyboard
    }
  },
  child: child, // this widget goes to the builder's child property. Made for better performance.
);

KeyboardVisibilityBuilder实现:

/// Calls `builder` on keyboard close/open.
/// https://stackoverflow.com/a/63241409/1321917
class KeyboardVisibilityBuilder extends StatefulWidget {
  final Widget child;
  final Widget Function(
    BuildContext context,
    Widget child,
    bool isKeyboardVisible,
  ) builder;

  const KeyboardVisibilityBuilder({
    Key key,
    this.child,
    @required this.builder,
  }) : super(key: key);

  @override
  _KeyboardVisibilityBuilderState createState() => _KeyboardVisibilityBuilderState();
}

class _KeyboardVisibilityBuilderState extends State<KeyboardVisibilityBuilder>
    with WidgetsBindingObserver {
  var _isKeyboardVisible = false;

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeMetrics() {
    final bottomInset = WidgetsBinding.instance.window.viewInsets.bottom;
    final newValue = bottomInset > 0.0;
    if (newValue != _isKeyboardVisible) {
      setState(() {
        _isKeyboardVisible = newValue;
      });
    }
  }

  @override
  Widget build(BuildContext context) => widget.builder(
        context,
        widget.child,
        _isKeyboardVisible,
      );
}

答案 1 :(得分:1)

不确定这是多么可靠,但是MediaQueryData上有此属性:

  /// The number of physical pixels on each side of the display rectangle into
  /// which the application can render, but over which the operating system
  /// will likely place system UI, such as the keyboard, that fully obscures
  /// any content.
  final EdgeInsets viewInsets;

viewInsets.vertical方法中检查build()是否大于零为我提供了正确的结果:

  @override
  Widget build(BuildContext context) {

    bool isKeyboardShowing = MediaQuery.of(context).viewInsets.vertical > 0;

    return SafeArea(
      child: Scaffold(
        body: Column(
          children: <Widget>[
            Text(isKeyboardShowing ? 'YES!' : 'NO!'),
            TextField(),
          ],
        ),
      ),
    );
  }

最好将其与其他检查(例如输入焦点)结合使用,以避免误报。

答案 2 :(得分:0)

您是否发现拼写错误?

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

应该是:

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

答案 3 :(得分:0)

每当用户按下或释放键盘上的键时,都会调用回调的小部件。

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

答案 4 :(得分:0)

if (MediaQuery.of(context).viewInsets.bottom > 0.0) {
   // keyboard on the screen
}

简单说明: MediaQuery ,以了解当前媒体的大小。此类用作 MediaQueryData media = MediaQuery.of(context); 。如果屏幕上出现任何视图,请 MediaQuery.of(context).viewInsets 赋予该视图高度一些值。由于键盘是从屏幕底部出现的,所以我使用 MediaQuery.of(context).viewInsets.bottom ,这使我在屏幕上占据了键盘的高度。当键盘不显示时,此值为0。此解决方案肯定有效。