开发原生页面的时候,在处理键盘事件上,通常的需求是,点击输入框外屏幕,要隐藏键盘,同样的,这样的需求也需要在 Flutter 上实现,
Android 上的实现方式是在基类 Activity 里实现事件分发,判断触摸位置是否在输入框内。
/** * 获取点击事件 */ @CallSuper @Override public boolean dispatchTouchEvent(MotionEvent ev) { if (ev.getAction() == MotionEvent.MotionEvent ) { View view = getCurrentFocus(); if (isShouldHideKeyBord(view, ev)) { hideSoftInput(view.getWindowToken()); } } return super.dispatchTouchEvent(ev); } /** * 判定当前是否需要隐藏 */ protected boolean isShouldHideKeyBord(View v, MotionEvent ev) { if (v != null && (v instanceof EditText)) { int[] l = {0, 0}; v.getLocationInWindow(l); int left = l[0], top = l[1], bottom = top + v.getHeight(), right = left + v.getWidth(); return !(ev.getX() > left && ev.getX() < right && ev.getY() > top && ev.getY() < bottom); } return false; } /** * 隐藏软键盘 */ private void hideSoftInput(IBinder token) { if (token != null) { InputMethodManager manager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); manager.hideSoftInputFromWindow(token, InputMethodManager.HIDE_NOT_ALWAYS); } }
那么在 Flutter 上如何实现呢?
许多文章的做法如下,每个包含TextField的屏幕中包裹GestureDetector,手动控制Focus。一旦失去焦点,就请求关闭键盘。这是一个临时的解决方案,容易出错,并且生成大量代码。
GestureDetector( behavior: HitTestBehavior.translucent, onTap: () { // 触摸收起键盘 FocusScope.of(context).requestFocus(FocusNode()); }, child: ******* }
通常这种需求是对应整个 app 的,有没有一劳永逸的方法呢?当然有,我们可以借助MaterialApp的builder方法,在 Navigator上方但在其他小部件下方插入小部件,仅添加了一个“全局” GestureDetector,它将为我们处理键盘关闭:
void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, visualDensity: VisualDensity.adaptivePlatformDensity, ), builder: (context, child) => Scaffold( // Global GestureDetector that will dismiss the keyboard body: GestureDetector( onTap: () { hideKeyboard(context); }, child: child, ), ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } void hideKeyboard(BuildContext context) { FocusScopeNode currentFocus = FocusScope.of(context); if (!currentFocus.hasPrimaryFocus && currentFocus.focusedChild != null) { FocusManager.instance.primaryFocus.unfocus(); } } }
当然也可以使用下面这个方法关闭键盘:
SystemChannels.textInput.invokeMethod('TextInput.hide');
这样就全局控制,再也不用在每个页面写了。
到此这篇关于详解Flutter点击空白隐藏键盘的全局做法的文章就介绍到这了,更多相关Flutter点击空白隐藏键盘内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!