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

时间:2018-09-02 20:15:37

标签: dart flutter

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

在回调完成时请求View3的构建是很简洁的,该回调在键盘完成动画设置后执行,但我看不到有任何方法。也许我缺少什么?

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

编辑

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

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

2 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:0)

当我将所有提到的解决方案放在一起时,对我来说效果很好:

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

  // This routine is invoked when the window metrics have changed.
  @override
  void didChangeMetrics() {
    final value = WidgetsBinding.instance.window.viewInsets.bottom;
    bool isVisible = value > 0;
    print("KEYBOARD VISIBLE: ${isVisible}");
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Center(
        child: TextField(),
      ),
    );
  }
}