首页 文章

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

提问于
浏览
1

我在Flutter中有一个页面,其中有几个小部件,包括TextField(我们称之为View1) . 当用户单击TextField时,我重建了仅显示TextField和键盘的页面(让我们调用此View2) . 当用户使用TextField完成时,我重新再次显示所有小部件的页面(让我们调用此View3,但请注意它与View1相同) . 除了一件事,这个工作正常 . 我得到一个临时的黄色/黑色指示器(在调试模式下),显示没有足够的空间来显示View3中的所有小部件 . 该指标只持续很短的时间,我最终得出结论,因为Flutter试图显示所有小部件,而键盘还没有完成动画 . 一旦键盘完成了动画,黄色/黑色条消失了,这就解释了为什么它只是短暂出现 .

在键盘完成动画播放时执行的回调中请求构建View3会很好,但是我没有看到任何方法 . 也许我错过了什么?

我可以想到解决这个问题的另一种方法是在构建View3之前插入一个延迟,以便让键盘有时间消失,但这似乎有些笨拙 . 有没有人有任何其他想法?

编辑

我添加了一个延迟如下,它的工作原理 . 尽管如此,看起来仍然有点hacky .

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

1 回答

  • 2

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

相关问题