When developing native pages, there is usually a requirement to hide the keyboard by clicking on the screen outside the input field. This requirement also needs to be implemented on Flutter.
The way to do this on Android is to implement event distribution in the base Activity class to determine whether the touch position is in the input box.
/** * get the click event */
@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);
}
/** * Determine if you need to hide */
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;
}
/** ** hide the soft keyboard */
private void hideSoftInput(IBinder token) {
if(token ! =null) { InputMethodManager manager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); manager.hideSoftInputFromWindow(token, InputMethodManager.HIDE_NOT_ALWAYS); }}Copy the code
So how does that happen with Flutter?
Many articles do this by wrapping the GestureDetector in each screen containing TextField and manually controlling the Focus. Once you lose focus, request that the keyboard be turned off. This is a temporary solution, error-prone, and generates a lot of code.
GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () {
// Touch the keyboard
FocusScope.of(context).requestFocus(FocusNode());
},
child: *******
}
Copy the code
Usually this requirement is for the entire app. Is there a way to fix it once and for all? Of course, we can use the MaterialApp’s Builder method to insert widgets above the Navigator but below the other widgets, adding only a “global” GestureDetector that will handle keyboard closing for us:
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(); }}}Copy the code
You can also use the following method to close the keyboard:
SystemChannels. (. InvokeMethod ('TextInput.hide');Copy the code
This is global control, no longer need to write on every page.