首页 > 解决方案 > 颤振检测键盘隐藏动画的结束

问题描述

我在 Flutter 中有一个页面,其中包含几个小部件,包括一个 TextField(我们称之为 View1)。当用户单击 TextField 时,我重建仅显示 TextField 和键盘的页面(让我们称之为 View2)。当用户使用 TextField 完成时,我再次重建页面,显示所有小部件(尽管请注意它与 View1 相同,但我们可以调用此 View3)。除了一件事之外,这很好用。我得到一个临时的黄色/黑色指示器(在调试模式下),表明没有足够的空间来显示 View3 中的所有小部件。该指标只持续很短的时间,我最终发现它似乎是因为 Flutter 正在尝试显示所有小部件,而键盘还没有完成动画。

在键盘完成动画后执行的回调中请求构建 View3 会很整洁,但我看不到任何这样做的方法。也许我错过了什么?

我能想到的解决此问题的另一种方法是在构建 View3 之前插入一个延迟,以便有时间让键盘消失,但这似乎有点 hacky。有没有人有其他想法?

编辑

我添加了如下延迟,它可以工作。不过看起来还是有点hacky。

Timer(Duration(milliseconds: 500),(){setState((){});});

标签: dartflutter

解决方案


尝试使用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(),
        ),
      );
    }
  }

推荐阅读