How can I dismiss the on screen keyboard?

前端 未结 18 2306
星月不相逢
星月不相逢 2020-11-30 18:31

I am collecting user input with a TextFormField and when the user presses a FloatingActionButton indicating they are done, I want to dismiss the on

相关标签:
18条回答
  • 2020-11-30 19:04

    As in Flutter everything is a widget, I decided to wrap the SystemChannels.textInput.invokeMethod('TextInput.hide'); and the FocusScope.of(context).requestFocus(FocusNode()); approach in a short utility module with a widget and a mixin in it.

    With the widget, you can wrap any widget (very convenient when using a good IDE support) with the 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(),
        );
      }
    }
    

    With the mixin, you can trigger hiding the keyboard from any state or widget upon any interaction:

    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, ...
          },
        );
      }
    }
    

    Just create a keyboard_hider.dart file and the widget and mixin are ready to use:

    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,
        );
      }
    }
    
    0 讨论(0)
  • 2020-11-30 19:05

    Note: This answer is outdated. See the answer for newer versions of Flutter.

    You can dismiss the keyboard by taking away the focus of the TextFormField and giving it to an unused FocusNode:

    FocusScope.of(context).requestFocus(FocusNode());
    
    0 讨论(0)
  • 2020-11-30 19:08

    try using a text editing controller. at the begining,

        final myController = TextEditingController();
         @override
      void dispose() {
        // Clean up the controller when the widget is disposed.
        myController.dispose();
        super.dispose();
      }
    

    and in the on press event,

    onPressed: () {
                commentController.clear();}
    

    this will dismiss the keybord.

    0 讨论(0)
  • 2020-11-30 19:10

    The example implementation of .unfocus() to auto hide keyboard when scrolling a list

    FocusScope.of(context).unfocus();
    

    you can find at

    https://github.com/flutter/flutter/issues/36869#issuecomment-518118441

    Thanks to szotp

    0 讨论(0)
  • 2020-11-30 19:14

    To summarize, this is a working solution for Flutter 1.17:

    Wrap your Widget like this:

    GestureDetector(
            onTap: FocusScope.of(context).unfocus,
            child: YourWidget(),
    );
    
    0 讨论(0)
  • 2020-11-30 19:14

    You can also declare a focusNode for you textfield and when you are done you can just call the unfocus method on that focusNode and also dispose it

    class MyHomePage extends StatefulWidget {
      MyHomePageState createState() => new MyHomePageState();
    }
    
    class MyHomePageState extends State<MyHomePage> {
      TextEditingController _controller = new TextEditingController();
    
    /// declare focus
      final FocusNode _titleFocus = FocusNode();
    
      @override
      void dispose() {
        _titleFocus.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(),
          floatingActionButton: new FloatingActionButton(
            child: new Icon(Icons.send),
            onPressed: () {
              setState(() {
                // send message
                // dismiss on screen keyboard here
    
                _titleFocus.unfocus();
                _controller.clear();
              });
            },
          ),
          body: new Container(
            alignment: FractionalOffset.center,
            padding: new EdgeInsets.all(20.0),
            child: new TextFormField(
              controller: _controller,
              focusNode: _titleFocus,
              decoration: new InputDecoration(labelText: 'Example Text'),
            ),
          ),
        );
      }
    }
    
    0 讨论(0)
提交回复
热议问题