我在Flutter中有一个页面,其中有几个小部件,包括TextField(我们称之为View1)。当用户单击TextField时,我重建了仅显示TextField和键盘的页面(让我们调用此View2)。当用户使用TextField完成时,我重新再次显示所有小部件的页面(让我们调用此View3,但请注意它与View1相同)。除了一件事,这个工作正常。我得到一个临时的黄色/黑色指示器(在调试模式下),显示没有足够的空间来显示View3中的所有小部件。该指标只持续很短的时间,我最终得出结论,因为Flutter试图显示所有小部件,而键盘还没有完成动画。一旦键盘完成了动画,黄色/黑色条消失了,这就解释了为什么它只是短暂出现。
在键盘完成动画播放时执行的回调中请求构建View3会很好,但是我没有看到任何方法。也许我错过了什么?
我可以想到解决这个问题的另一种方法是在构建View3之前插入一个延迟,以便让键盘有时间消失,但这似乎有点笨拙。有没有人有任何其他想法?
编辑
我添加了一个延迟如下,它的工作原理。尽管如此,看起来仍然有点hacky。
Timer(Duration(milliseconds: 500),(){setState((){});});
尝试使用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(),
),
);
}
}