颤动键盘听隐藏和显示

Gre*_*Eye 13 flutter

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

我试过这个例子 如何在屏幕上听键盘Flutter?

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

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

TextField _myTextField = new TextField(
        focusNode: _mynNode,
        ...
        ...
    );
Run Code Online (Sandbox Code Playgroud)

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

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

And*_*eev 9

键盘可见性构建器

可以使用WidgetsBindingObservermixin来监听键盘显示/隐藏事件。我准备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.
);
Run Code Online (Sandbox Code Playgroud)

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,
      );
}
Run Code Online (Sandbox Code Playgroud)

  • 我用它来在键盘关闭时验证输入字段,而不是在按下“应用”按钮时验证 (2认同)
  • `WidgetsBinding.instance.window` 已被弃用,请使用 `WidgetsBinding.instance.platformDispatcher.views.first.viewInsets.bottom` (2认同)

Utk*_* A. 7

有一个包完全满足您的要求。请检查:flutter_keyboard_visibility

在那里,通过使用 StreamSubscription,您可以监听键盘是否向上/向下移动,并据此做出反应。


Vin*_*nto 6

不确定这有多可靠,但有这个属性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;
Run Code Online (Sandbox Code Playgroud)

检查方法中是否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(),
          ],
        ),
      ),
    );
  }
Run Code Online (Sandbox Code Playgroud)

将此与其他检查(例如输入焦点)结合起来可能是一个好主意,以避免误报。


Abd*_*odi 6

我需要的是一个监听器,所以我将Andrey Gordeev代码转换为

    import 'package:flutter/cupertino.dart';

class KeyboardVisibilityListener extends StatefulWidget {
  final Widget child;
  final void Function(
    bool isKeyboardVisible,
  ) listener;

  const KeyboardVisibilityListener({
    Key? key,
    required this.child,
    required this.listener,
  }) : super(key: key);

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

class _KeyboardVisibilityListenerState extends State<KeyboardVisibilityListener>
    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) {
      _isKeyboardVisible = newValue;
      widget.listener(_isKeyboardVisible);
    }
  }

  @override
  Widget build(BuildContext context) => widget.child;
}
Run Code Online (Sandbox Code Playgroud)

我用它在隐藏键盘时取消输入字段的焦点

home: KeyboardVisibilityListener(
        listener: (isKeyboardVisible) {
          if (!isKeyboardVisible) {
            FocusManager.instance.primaryFocus?.unfocus();
          }
        },
        child: Scaffold(
          key: scaffoldKey,
          body: layoutp.currentItem.page,
        ),
      ),
Run Code Online (Sandbox Code Playgroud)