颤振检测键盘隐藏动画的结尾

iBo*_*101 3 dart flutter

我在Flutter中有一个页面,其中包含几个小部件,包括一个TextField(我们称其为View1)。当用户单击TextField时,我将重建仅显示TextField和键盘的页面(我们将其称为View2)。当用户完成TextField的操作后,我将重新构建页面,再次像以前一样显示所有小部件(尽管将其称为View1,但仍将其称为View3)。除了一件事,这工作正常。我得到一个临时的黄色/黑色指示器(在调试模式下),该指示器指示没有足够的空间来显示View3中的所有小部件。该指示器仅持续了很短的时间,我最终发现它似乎是因为Flutter试图在键盘尚未完成动画移动时显示所有小部件。

要求在回调完成时请求View3的构建是很巧妙的,当键盘完成动画处理后,该回调将执行,但是我看不到这样做的任何方法。也许我缺少什么?

我可以考虑解决此问题的另一种方法是在构建View3之前插入一个延迟,以留出时间让键盘消失,但这似乎有点不客气。还有其他想法吗?

编辑

我添加了一个延迟,如下所示。似乎还是有点hacky。

Timer(Duration(milliseconds: 500),(){setState((){});});
Run Code Online (Sandbox Code Playgroud)

die*_*per 8

尝试使用WidgetsBindingObserver并覆盖这样的didChangeMetrics方法:

  class KeyboardTogglePage extends StatefulWidget {
    @override
    _KeyboardTogglePageState createState() => _KeyboardTogglePageState();
  }

  class _KeyboardTogglePageState extends State<KeyboardTogglePage>
      with WidgetsBindingObserver {
    @override
    void initState() {
      super.initState();
      WidgetsBinding.instance.addObserver(this);
    }

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

    var isKeyboardOpen = false;

    ///
    /// This routine is invoked when the window metrics have changed.
    ///
    @override
    void didChangeMetrics() {
      final value = MediaQuery.of(context).viewInsets.bottom;
      if (value > 0) {
        if (isKeyboardOpen) {
          _onKeyboardChanged(false);
        }
        isKeyboardOpen = false;
      } else {
        isKeyboardOpen = true;
        _onKeyboardChanged(true);
      }
    }

    _onKeyboardChanged(bool isVisible) {
      if (isVisible) {
        print("KEYBOARD VISIBLE");
      } else {
        print("KEYBOARD HIDDEN");
      }
    }

    @override
    Widget build(BuildContext context) {
      return Container(
        child: Center(
          child: TextField(),
        ),
      );
    }
  }
Run Code Online (Sandbox Code Playgroud)

  • 通常,这是对键盘更改做出反应的绝佳解决方案。我注意到使用final value = MediaQuery.of(context).viewInsets.bottom`得到的结果不正确,其中“ final value = WidgetsBinding.instance.window.viewInsets.bottom”的效果更好 (2认同)