如何判断键盘是否显示或隐藏?
我试过这个例子 How to listen to keyboard on screen Flutter?
void _listener(){
if(_myNode.hasFocus){
// keyboard appeared
}else{
// keyboard dismissed
}
}
FocusNode _myNode = new FocusNode()..addListener(_listner);
TextField _myTextField = new TextField(
focusNode: _mynNode,
...
...
);
但不幸的是它不起作用。有什么想法可以听取键盘的变化吗?
当我按下" Done"它似乎有效。在键盘上。但是,如果我按下我的手机,它就不会去键盘被解雇"因为焦点仍然存在..有任何帮助吗?
答案 0 :(得分:3)
使用WidgetsBindingObserver
mixin可以监听键盘的显示/隐藏事件。我准备了KeyboardVisibilityBuilder
小部件来为您处理行为。用法与AnimatedBuilder
非常相似:
return KeyboardVisibilityBuilder(
builder: (context, child, isKeyboardVisible) {
if (isKeyboardVisible) {
// build layout for visible keyboard
} else {
// build layout for invisible keyboard
}
},
child: child, // this widget goes to the builder's child property. Made for better performance.
);
KeyboardVisibilityBuilder
实现:
/// Calls `builder` on keyboard close/open.
/// https://stackoverflow.com/a/63241409/1321917
class KeyboardVisibilityBuilder extends StatefulWidget {
final Widget child;
final Widget Function(
BuildContext context,
Widget child,
bool isKeyboardVisible,
) builder;
const KeyboardVisibilityBuilder({
Key key,
this.child,
@required this.builder,
}) : super(key: key);
@override
_KeyboardVisibilityBuilderState createState() => _KeyboardVisibilityBuilderState();
}
class _KeyboardVisibilityBuilderState extends State<KeyboardVisibilityBuilder>
with WidgetsBindingObserver {
var _isKeyboardVisible = false;
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeMetrics() {
final bottomInset = WidgetsBinding.instance.window.viewInsets.bottom;
final newValue = bottomInset > 0.0;
if (newValue != _isKeyboardVisible) {
setState(() {
_isKeyboardVisible = newValue;
});
}
}
@override
Widget build(BuildContext context) => widget.builder(
context,
widget.child,
_isKeyboardVisible,
);
}
答案 1 :(得分:1)
不确定这是多么可靠,但是MediaQueryData
上有此属性:
/// The number of physical pixels on each side of the display rectangle into
/// which the application can render, but over which the operating system
/// will likely place system UI, such as the keyboard, that fully obscures
/// any content.
final EdgeInsets viewInsets;
在viewInsets.vertical
方法中检查build()
是否大于零为我提供了正确的结果:
@override
Widget build(BuildContext context) {
bool isKeyboardShowing = MediaQuery.of(context).viewInsets.vertical > 0;
return SafeArea(
child: Scaffold(
body: Column(
children: <Widget>[
Text(isKeyboardShowing ? 'YES!' : 'NO!'),
TextField(),
],
),
),
);
}
最好将其与其他检查(例如输入焦点)结合使用,以避免误报。
答案 2 :(得分:0)
您是否发现拼写错误?
FocusNode _myNode = new FocusNode()..addListener(_listner);
应该是:
FocusNode _myNode = new FocusNode()..addListener(_listener);
答案 3 :(得分:0)
每当用户按下或释放键盘上的键时,都会调用回调的小部件。
RawKeyboardListener对于侦听原始键事件和表示为键的硬件按钮很有用。通常用于游戏和其他使用键盘输入文字以外的目的的应用。
对于文本输入,请考虑使用EditableText,该文本与屏幕键盘和输入法编辑器(IME)集成。
const RawKeyboardListener({
Key key,
@required FocusNode focusNode,
@required ValueChanged<RawKeyEvent> onKey,
@required Widget child
})
创建一个接收原始键盘事件的小部件。
对于文本输入,请考虑使用EditableText,该文本与屏幕键盘和输入法编辑器(IME)集成。
实施
const RawKeyboardListener({
Key key,
@required this.focusNode,
@required this.onKey,
@required this.child,
}) : assert(focusNode != null),
assert(child != null),
super(key: key);
答案 4 :(得分:0)
if (MediaQuery.of(context).viewInsets.bottom > 0.0) {
// keyboard on the screen
}
简单说明: MediaQuery ,以了解当前媒体的大小。此类用作 MediaQueryData media = MediaQuery.of(context); 。如果屏幕上出现任何视图,请 MediaQuery.of(context).viewInsets 赋予该视图高度一些值。由于键盘是从屏幕底部出现的,所以我使用 MediaQuery.of(context).viewInsets.bottom ,这使我在屏幕上占据了键盘的高度。当键盘不显示时,此值为0。此解决方案肯定有效。