问题描述
我有一个TextField小部件,可以在列表中添加播放器。但是我希望键盘在添加播放器时保持焦点,并且在提交时,键盘保持焦点松散。.有什么想法吗?
这是我的TextField小部件:
TextField(
textCapitalization: TextCapitalization.words,onChanged: (val) => playerName = val.trim(),onSubmitted: (val) {
if (playerName != null && playerName != '') {
Provider.of<PlayerProvider>(context,listen: false).addplayer(playerName);
HapticFeedback.lightImpact();
}
},maxLength: 19,autocorrect: false,decoration: new Inputdecoration(
counterText: "",border: new OutlineInputBorder(
borderSide: BorderSide.none,borderRadius: const BorderRadius.all(
const Radius.circular(30.0),),filled: true,contentPadding: EdgeInsets.symmetric(vertical: 0,horizontal: 20),hintStyle: GoogleFonts.rubik(color: Colors.grey[500],fontWeight: FontWeight.bold),hintText: AppLocalizations.of(context).translate('player_selection_page_hint'),fillColor: Colors.white),)
顺便说一句,autofocus: true
可以工作,但是有点像键盘没有对准焦点,并且可以立即将焦点移回……所以观看起来并不好。所以,如果您还有其他想法。
解决方法
我认为您应该尝试使用FocusNode。
class MyCustomForm extends StatefulWidget {
@override
_MyCustomFormState createState() => _MyCustomFormState();
}
// Define a corresponding State class.
// This class holds data related to the form.
class _MyCustomFormState extends State<MyCustomForm> {
// Define the focus node. To manage the lifecycle,create the FocusNode in
// the initState method,and clean it up in the dispose method.
FocusNode myFocusNode;
@override
void initState() {
super.initState();
myFocusNode = FocusNode();
}
@override
void dispose() {
// Clean up the focus node when the Form is disposed.
myFocusNode.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return TextField(
focusNode: myFocusNode
textCapitalization: TextCapitalization.words,onChanged: (val) => playerName = val.trim(),onSubmitted: (val) {
if (playerName != null && playerName != '') {
Provider.of<PlayerProvider>(context,listen: false).addPlayer(playerName);
HapticFeedback.lightImpact();
}
myFocusNode.requestFocus();
},maxLength: 19,autocorrect: false,decoration: new InputDecoration(
counterText: "",border: new OutlineInputBorder(
borderSide: BorderSide.none,borderRadius: const BorderRadius.all(
const Radius.circular(30.0),),filled: true,contentPadding: EdgeInsets.symmetric(vertical: 0,horizontal: 20),hintStyle: GoogleFonts.rubik(color: Colors.grey[500],fontWeight: FontWeight.bold),hintText: AppLocalizations.of(context).translate('player_selection_page_hint'),fillColor: Colors.white),);
}
}
,
好吧,您可以使用FocusNode。
但是我有一个解决方法。
我通常设置
.container {
height: 100px
}
.container .is-active {
height: 200px;
并且在验证器中总是返回一些文本。
因此,每当用户单击文本字段时,它都不会失去焦点。
因此,颤动始终使焦点集中在文本字段上。
但是,为此,您必须使用TextFormField。
但是正确的方法是使用FocusNode。 这是代码。
autovalidate:true
然后您可以使用它来调用onSaved方法
TextFormField (
autovalidate : true
validator: (value) {
return '';
},textCapitalization: TextCapitalization.words,onSaved: (val) {
if (playerName != null && playerName != '') {
Provider.of<PlayerProvider>(context,listen: false).addPlayer(playerName);
HapticFeedback.lightImpact();
}
},decoration: new InputDecoration(
counterText: "",border: new OutlineInputBorder(
borderSide: BorderSide.none,borderRadius: const BorderRadius.all(
const Radius.circular(30.0),errorBorder: OutlineInputBorder(
borderSide: BorderSide.none,focusedErrorBorder: OutlineInputBorder(
borderSide: BorderSide.none,)
此处_formKey
_formKey.currentState.save(); // And it will call the onSaved method
包装出现文本框的整个小部件树。