颤振检测键盘隐藏动画的结束
Posted
技术标签:
【中文标题】颤振检测键盘隐藏动画的结束【英文标题】:Flutter detect end of keyboard hide animation 【发布时间】:2018-09-02 20:15:36 【问题描述】:我在 Flutter 中有一个页面,其中包含几个小部件,包括一个 TextField(我们称之为 View1)。当用户单击 TextField 时,我重建仅显示 TextField 和键盘的页面(让我们称之为 View2)。当用户完成 TextField 后,我再次重建页面,显示所有小部件(尽管请注意它与 View1 相同,但我们称之为 View3)。除了一件事之外,这很好用。我得到一个临时的黄色/黑色指示器(在调试模式下),表明没有足够的空间来显示 View3 中的所有小部件。该指标只持续很短的时间,我最终发现它似乎是因为 Flutter 正在尝试显示所有小部件,而键盘还没有完成动画。一旦键盘完成动画,黄色/黑色条就会消失,这解释了我认为它为什么只出现短暂的原因。
在键盘完成动画后执行的回调中请求构建 View3 会很好,但我看不到任何这样做的方法。也许我错过了什么?
我能想到的解决此问题的另一种方法是在构建 View3 之前插入延迟,以便有时间让键盘消失,但这似乎有点 hacky。还有其他想法吗?
编辑
我添加了如下延迟,它可以工作。不过看起来还是有点老套。
Timer(Duration(milliseconds: 500),()setState(()););
【问题讨论】:
我同意添加时间延迟看起来很老套。听键盘和显示 View3 对我来说也听起来有点 hacky。你能显示在转换过程中发生的错误并且可能是一些代码吗? 【参考方案1】:尝试使用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(),
),
);
【讨论】:
这是对一般键盘更改做出反应的绝佳解决方案。我注意到final value = MediaQuery.of(context).viewInsets.bottom
得到的结果不正确,而final value = WidgetsBinding.instance.window.viewInsets.bottom
效果更好
嘿兄弟,谢谢。它比库更好地检查键盘是否打开。只有一个小错误。 if (value > 0) if (isKeyboardOpen) _onKeyboardChanged(false);->这是真的 isKeyboardOpen = false; 其他 isKeyboardOpen = true; _onKeyboardChanged(true);-> 这是假的 【参考方案2】:
当我将所有提到的解决方案放在一起时,它对我来说效果很好:
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(),
),
);
【讨论】:
以上是关于颤振检测键盘隐藏动画的结束的主要内容,如果未能解决你的问题,请参考以下文章