我知道不专心的一般答案是使用这段代码:FocusScope.of(context).requestFocus(new FocusNode());
但是当TextField具有自定义focusNode时,此代码似乎无效。
SystemChannels.textInput.invokeMethod('TextInput.hide');
仍然有效,但是只能移除键盘-字段本身仍处于选中状态。
代码(删除了不相关的部分):
class RegisterScreen extends StatelessWidget {
final phoneNumberTEC = TextEditingController();
final passwordTEC = TextEditingController();
final passwordFocusNode = FocusNode();
@override
Widget build(BuildContext context) {
return this.keyboardDismisser(
context: context,
child: Scaffold(
appBar: new AppBar(
title: new Text("Register"),
),
body: this.page(context),
resizeToAvoidBottomPadding: false,
),
);
}
Widget keyboardDismisser({BuildContext context, Widget child}) {
final gesture = GestureDetector(
onTap: () {
this.passwordFocusNode.unfocus();
FocusScope.of(context).requestFocus(new FocusNode());
SystemChannels.textInput.invokeMethod('TextInput.hide');
},
child: child,
);
return gesture;
}
Widget page(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Container(
padding: new EdgeInsets.all(16.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
this.phoneNumberTextField(context),
this.passwordTextField(context),
]
),
),
// cutting irrelevant widgets out
)
]
);
}
Widget phoneNumberTextField(BuildContext context) {
return TextField(
controller: this.phoneNumberTEC,
decoration: InputDecoration(hintText: "Phone number"),
onSubmitted: (string) {
FocusScope.of(context).requestFocus(this.passwordFocusNode);
},
);
}
Widget passwordTextField(BuildContext context) {
return TextField(
controller: this.passwordTEC,
decoration: InputDecoration(hintText: "Password"),
obscureText: true,
focusNode: this.passwordFocusNode,
onSubmitted: (string) {
this.performRegister(context);
},
);
}
}
答案 0 :(得分:36)
这里的答案与@kasiara的答案类似,只是另一种方式。
FocusScope.of(context).unfocus();
_textEditingController.clear();
答案 1 :(得分:5)
这里适用于新的 Flutter 版本:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return Listener(
onPointerDown: (_) {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.focusedChild?.unfocus();
}
},
child: MaterialApp(
title: 'Flutter Demo',
home: Scaffold(body: SafeArea(child: TextField())),
),
);
}
}
答案 2 :(得分:4)
您可能已经看到有些人使用这种方法:
FocusScope.of(context).requestFocus(new FocusNode());
在这种方法中,您是动态创建一个 FocusNode 而不是处理它。虽然这也有效,但不建议这样做,因为 FocusNode 是持久性对象,您应该处理它们以避免内存泄漏:
@override
void dispose() {
focusNode.dispose();
super.dispose();
}
看看这个link。作者对如何以最佳和正确的方式做到这一点有很好的解释。祝你有美好的一天:)
答案 3 :(得分:3)
与@Blasanka相似,但更短。 将其放在包装整个页面的GestureDetector中。
Joiner
答案 4 :(得分:2)
在我的情况下,我有一个Private Sub Workbook_Open()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Sheets
With ws
If .Range("W6").Value = 0 Then
HideFG ws
Else
HideF ws
End If
End With
Next
End Sub
Sub HideF(wsht As Worksheet)
'
' HideF Macro
'
'
For i = 1 To wsht.Shapes.Count
wsht.Shapes(i).Visible = msoTrue
Next i
wsht.Shapes.Range(Array("F")).Visible = msoFalse
Application.CommandBars("Selection").Visible = False
End Sub
Sub HideFG(wsht As Worksheet)
'
' HideFG Macro
'
'
For i = 1 To wsht.Shapes.Count
wsht.Shapes(i).Visible = msoTrue
Next i
wsht.Shapes.Range(Array("FG")).Visible = msoFalse
Application.CommandBars("Selection").Visible = False
End Sub
,我想从中移开焦点并在可能的情况下隐藏键盘。下面的代码可以同时清除TextField的内容。
TextFormField
其中 _textEditingController 只是处于窗口小部件状态的FocusScope.of(context).requestFocus(new FocusNode()); //remove focus
WidgetsBinding.instance.addPostFrameCallback((_) => _textEditingController.clear()); // clear content
。
答案 5 :(得分:2)
用 GestureDetector Widget 包裹页面 Root Widget。这对我有用
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
FocusScope.of(context).unfocus();
new TextEditingController().clear();
},
child: _yourPageRootWidget(..)
)
}
答案 6 :(得分:0)
出来,我没有正确管理FocusNode的生命周期:https://flutter.io/docs/cookbook/forms/focus
因此,以下代码确实对我有用:
class RegisterScreen extends StatefulWidget {
@override
_RegisterScreenState createState() => _RegisterScreenState();
}
class _RegisterScreenState extends State<RegisterScreen> {
final phoneNumberTEC = TextEditingController();
final passwordTEC = TextEditingController();
FocusNode passwordFocusNode;
@override
void initState() {
super.initState();
this.passwordFocusNode = FocusNode();
}
@override
void dispose() {
this.passwordFocusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return this.keyboardDismisser(
context: context,
child: Scaffold(
appBar: new AppBar(
title: new Text("Register"),
),
body: this.page(context),
resizeToAvoidBottomPadding: false,
),
);
}
Widget keyboardDismisser({BuildContext context, Widget child}) {
final gesture = GestureDetector(
onTap: () {
FocusScope.of(context).requestFocus(new FocusNode());
debugPrint("!!!");
},
child: child,
);
return gesture;
}
// ...
}
感谢@SnakeyHips的帮助-当问题可以在我的身边重现时,无法重现该问题,这给了我一些想法:)
答案 7 :(得分:0)
@override
Widget build(BuildContext context) {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
return Material(
child: Scaffold(
仅添加新功能(页面)标题,(返回主屏幕自动关闭键盘)