Como no Flutter tudo é um widget, decidi envolver o SystemChannels.textInput.invokeMethod('TextInput.hide');
e a FocusScope.of(context).requestFocus(FocusNode());
abordagem em um pequeno módulo de utilitário com um widget e um mixin nele.
Com o widget, você pode envolver qualquer widget (muito conveniente ao usar um bom suporte IDE) com o KeyboardHider
widget:
class SimpleWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return KeyboardHider(
/* Here comes a widget tree that eventually opens the keyboard,
* but the widget that opened the keyboard doesn't necessarily
* takes care of hiding it, so we wrap everything in a
* KeyboardHider widget */
child: Container(),
);
}
}
Com o mixin, você pode ativar a ocultação do teclado de qualquer estado ou widget em qualquer interação:
class SimpleWidget extends StatefulWidget {
@override
_SimpleWidgetState createState() => _SimpleWidgetState();
}
class _SimpleWidgetState extends State<SimpleWidget> with KeyboardHiderMixin {
@override
Widget build(BuildContext context) {
return RaisedButton(
onPressed: () {
// Hide the keyboard:
hideKeyboard();
// Do other stuff, for example:
// Update the state, make an HTTP request, ...
},
);
}
}
Basta criar um keyboard_hider.dart
arquivo e o widget e o mixin estarão prontos para uso:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
/// Mixin that enables hiding the keyboard easily upon any interaction or logic
/// from any class.
abstract class KeyboardHiderMixin {
void hideKeyboard({
BuildContext context,
bool hideTextInput = true,
bool requestFocusNode = true,
}) {
if (hideTextInput) {
SystemChannels.textInput.invokeMethod('TextInput.hide');
}
if (context != null && requestFocusNode) {
FocusScope.of(context).requestFocus(FocusNode());
}
}
}
/// A widget that can be used to hide the text input that are opened by text
/// fields automatically on tap.
///
/// Delegates to [KeyboardHiderMixin] for hiding the keyboard on tap.
class KeyboardHider extends StatelessWidget with KeyboardHiderMixin {
final Widget child;
/// Decide whether to use
/// `SystemChannels.textInput.invokeMethod('TextInput.hide');`
/// to hide the keyboard
final bool hideTextInput;
final bool requestFocusNode;
/// One of hideTextInput or requestFocusNode must be true, otherwise using the
/// widget is pointless as it will not even try to hide the keyboard.
const KeyboardHider({
Key key,
@required this.child,
this.hideTextInput = true,
this.requestFocusNode = true,
}) : assert(child != null),
assert(hideTextInput || requestFocusNode),
super(key: key);
@override
Widget build(BuildContext context) {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () {
hideKeyboard(
context: context,
hideTextInput: hideTextInput,
requestFocusNode: requestFocusNode,
);
},
child: child,
);
}
}