Flutter中在收起键盘时自动使TextField失去焦点

前言
最近在做公司flutter项目的时候,接到了一个需求,本质上就是实现收起键盘的时候让TextField组件失去焦点的功能。

这个需求乍一看很好解决,心想,就这!就这!就这!so easy!

但是!但是!但是!万万没想到啊,实现时候却让我本来就很稀薄的头发雪上加霜,原因就是安卓手机第三方输入法有一个很蛋疼的地方,就是他会有一个收起键盘的按钮,如下图所示:
image

问题就在,这!个!按!钮!他不属于原生键盘按钮,无法检测到键盘事件!并且不能够屏蔽!👴真的要给搞崩溃了。下面就给兄弟萌说说我最后的解题思路,希望能有所帮助!

解题思路
上面说过,键盘事件无法监听,所以我只能另外想办法。能不能监听键盘关闭呢?通过一番查找,得出的答案是可以,那么就来搞一下!

keyboard_visibility
地址: https://pub.dev/packages/keyb…
这个库可以用来监听键盘的弹出和收起,引用库里的例子:

import ‘package:keyboard_visibility/keyboard_visibility.dart’;

@protected
void initState() {
super.initState();

KeyboardVisibilityNotification().addNewListener(
onChange: (bool visible) {
print(visible);
},
);
}
通常来讲,这个就完全可以解决我们的需求,但是!事情并没有这么简单!我们在升级了flutter版本之后,发现无法打包apk,最后提示是keyboard_visibility不!兼!容!查了一下资料发现,这个库应该是作者停更了,没有做到与时俱进,这咋整!

image

由于网上相关资料极少,科学上网也不能立刻解决我的问题,万般无奈之下,只能换个思路。那能不能监听界面的高度变化?经过查找资料,得出的结论是可以这样做的。

WidgetsBindingObserver & didChangeMetrics
这个组件可以监听页面的一些生命周期,并且其中有一个回调didChangeMetrics可以监听界面高度的变化。其中键盘的弹出和收起这些其实都属于高度的变化自然也是可以监听到的。

Nice!看到这里,那么我们的解决方案也就有了,那就是设置一个flag,区分出来什么时候键盘弹出,什么时候键盘收起。

class _InputState extends State with WidgetsBindingObserver {
// 输入框的焦点实例
FocusNode _focusNode;
// 当前键盘是否是激活状态
bool isKeyboardActived = false;

@override
void initState() {
super.initState();
_focusNode = FocusNode();
// 监听输入框焦点变化
_focusNode.addListener(_onFocus);
// 创建一个界面变化的观察者
WidgetsBinding.instance.addObserver(this);
}

@override
void didChangeMetrics() {
super.didChangeMetrics();
WidgetsBinding.instance.addPostFrameCallback((_) {
// 当前是安卓系统并且在焦点聚焦的情况下
if (Platform.isAndroid && _focusNode.hasFocus) {
if (isKeyboardActived) {
isKeyboardActived = false;
// 使输入框失去焦点
_focusNode.unfocus();
return;
}
isKeyboardActived = true;
}
});
}

// 既然有监听当然也要有卸载,防止内存泄漏嘛
@override
void dispose() {
super.dispose();
_focusNode.dispose();
WidgetsBinding.instance.removeObserver(this);
}

// 焦点变化时触发的函数
_onFocus() {
if (_focusNode.hasFocus) {
// 聚焦时候的操作
return;
}

// 失去焦点时候的操作
isKeyboardActived = false;

}

@override
Widget build(BuildContext context) {
return TextField(
focusNode: _focusNode,
textInputAction: TextInputAction.done,
);
}
}
这样就大功告成了,测试之后暂时没发现什么大问题,还是比较好用的。

参考文章
WidgetsBindingObserver监测页面生命周期

Flutter的生命周期(交互)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flutter,可以通过使用TextField组件来获取焦点TextField组件是一个用于接收用户输入的文本框,它有一个focusNode属性可以用来控制焦点。 首先,我们需要在StatefulWidget的构建方法创建一个FocusNode对象,并在TextField组件的focusNode属性传入该对象。例如: ``` class MyWidget extends StatefulWidget { @override _MyWidgetState createState() => _MyWidgetState(); } class _MyWidgetState extends State<MyWidget> { FocusNode myFocusNode; @override void initState() { super.initState(); myFocusNode = FocusNode(); } @override void dispose() { myFocusNode.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return TextField( focusNode: myFocusNode, // 其他TextField的属性... ); } } ``` 接下来,我们可以使用myFocusNode.requestFocus()方法在代码的某个位置来获取焦点。例如,我们可以在按钮的点击事件获取焦点: ``` RaisedButton( onPressed: () { myFocusNode.requestFocus(); }, child: Text("获取焦点"), ), ``` 当按钮被点击TextField将会获取焦点并弹出键盘供用户输入。 另外,通过myFocusNode.requestFocus方法获取焦点并不会触发键盘自动弹出的效果,如果需要自动弹出键盘,可以将myFocusNode传入TextField的autofocus属性: ``` TextField( focusNode: myFocusNode, autofocus: true, // 其他TextField的属性... ); ``` 这样,在页面加载完成后,TextField组件将会自动获取焦点并弹出键盘
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值