如何关闭屏幕键盘?

478

我正在使用 TextFormField 收集用户输入,当用户按下 FloatingActionButton 表示完成后,我希望关闭屏幕键盘。

如何让键盘自动消失?

import 'package:flutter/material.dart';

class MyHomePage extends StatefulWidget {
  MyHomePageState createState() => new MyHomePageState();
}

class MyHomePageState extends State<MyHomePage> {
  TextEditingController _controller = new TextEditingController();

  @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
            _controller.clear();
          });
        },
      ),
      body: new Container(
        alignment: FractionalOffset.center,
        padding: new EdgeInsets.all(20.0),
        child: new TextFormField(
          controller: _controller,
          decoration: new InputDecoration(labelText: 'Example Text'),
        ),
      ),
    );
  }
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new MyHomePage(),
    );
  }
}

void main() {
  runApp(new MyApp());
}

1
以下是2021年5月的推荐解决方案 - Son Nguyen
先生,您能否请查看与Flutter相关的以下问题。下面的链接是我在Stack Overflow上发布的问题链接-----https://stackoverflow.com/questions/69640226/how-to-create-shapes-or-alphabets-by-joining-dots-join-dots-for-creating-shap。 - Jithu Hari
34个回答

3
在Flutter 3.7.2中,可以使用GestureDetector将Scaffold包装起来,以便在点击屏幕其他地方时关闭键盘。
GestureDetector(
   onTap: () {
      SystemChannels.textInput.invokeMethod<void>('TextInput.hide');
   },
   child: Scaffold(),
),

2
您可以为文本字段声明一个focusNode,当您完成后,只需在该focusNode上调用unfocus方法并且dispose它即可。
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'),
        ),
      ),
    );
  }
}

2

请在构建部件中添加以下代码

    FocusScope.of(context).requestFocus(FocusNode());

以下解决方案不建议使用,如果您想再次聚焦文本框,它会造成麻烦。 下面的解决方案是通过 if 语句实现的完美解决方法。closeKeyboard(BuildContext context) { var currentFocus = FocusScope.of(context); if (!currentFocus.hasPrimaryFocus) { currentFocus.unfocus(); } } - Shoaib Kakal

2
你可以使用以下代码: FocusScope.of(context).requestFocus(FocusNode()); 你可以在GestureDetectorInkWellonTap中像这样使用它:
GestureDetector(
  onTap: () {
    // THIS FOCUS SCOPE WILL CLOSE THE KEYBOARD
    FocusScope.of(context).requestFocus(FocusNode());
    forgotPasswordAPI(emailController.text);
  },
}
 

2
如果您的键盘仍然无法关闭,请不要忘记将focusNode添加到TextField中。上面的信息很有帮助,但是忘记添加focusNode让我有点困扰。这里有一个示例。
TextField(
          focusNode: FocusNode(),
          textController: _controller,
          autoFocus: false,
          textStyle: TextStyle(fontSize: 14),
          onFieldSubmitted: (text) {},
          onChanged: (text) {},
          hint: 'Enter the code',
          hintColor: CustomColors.mediumGray,
          suffixAsset: _voucherController.text.length == 7
              ? Assets.ic_approved_voucher
              : null,
          isIcon: false,
          isObscure: false,
          maxLength: 7,
        )



closeKeyboard(BuildContext context) {
    var currentFocus = FocusScope.of(context);
    if (!currentFocus.hasPrimaryFocus) {
      currentFocus.unfocus();
    }
  }

  @override
  Widget build(BuildContext context) {
    _keyboardVisible = MediaQuery.of(context).viewInsets.bottom != 0;
    size = MediaQuery.of(context).size;
    return GestureDetector(
      onTap: () {
        closeKeyboard(context);
      },
      child: Scaffold(
        backgroundColor: Colors.white,
        body: Container(
            width: double.maxFinite,
            height: double.maxFinite,
            child: _buildUI(vm)),
      ),
    );
  }

1

当使用过滤的listView时,使用FocusScope.of(context).unfocus()存在缺点。除了这些细节和简洁外,在https://pub.dev/packages/keyboard_dismisser中使用keyboard_dismisser包将解决所有问题。


请遵循以下链接了解如何撰写优秀的回答:如何撰写好的回答? - Willie Cheng
什么是缺点? - SametSahin

1
使用SystemChannels.textInput.invokeMethod('TextInput.hide');。在屏幕加载时,该命令将关闭/隐藏键盘。
void initState() {
  super.initState();
  SystemChannels.textInput.invokeMethod('TextInput.hide');
}

1

FocusScope.of(context).unfocus(); 不起作用。

这段代码在我的 Flutter 版本 2.2.3 和空安全中有效。

WidgetsBinding.instance?.focusManager.primaryFocus?.unfocus()

来源:https://github.com/flutter/flutter/issues/20227#issuecomment-512860882 例如,将此代码放在MyAppState中,以应用在整个应用程序中点击屏幕其他区域时隐藏键盘的功能。
return GestureDetector(
  onTap: () =>
      WidgetsBinding.instance?.focusManager.primaryFocus?.unfocus(),
  child: MaterialApp(
    title: 'Flutter Demo',
    theme: getTheme(),
    home: _body(),
  ),
);

1
我已经将这个函数添加到我的基础代码中,目前运行良好!
void hideKeyword(BuildContext context) {
  FocusScopeNode currentFocus = FocusScope.of(context);
  if (!currentFocus.hasPrimaryFocus && currentFocus.focusedChild != null) {
    currentFocus.focusedChild.unfocus();
  }
}

1
首先将TextFieldfocusNode连接起来。
 TextField(
focusNode: focusNode),

现在要显示/打开键盘,请调用以下方法。
focusNode.requestFocus();

隐藏/关闭键盘的调用方法是:
 focusNode.unfocus();

如果你想知道键盘在那个时候是否可见,请检查下面的条件。
最终的keyBoardVisible = MediaQuery.of(context).viewInsets.bottom != 0;
在这里,如果键盘可见,keyBoardVisible的值为true,如果键盘被隐藏,值为false。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接