以下是相关代码。 onFieldSubmitted:中的debugPrint()正在运行,因此代码正在到达此处,但是焦点没有改变。焦点不会改变。
_createItemHeadingWidget() {
return Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
controller: _controllerItemHed,
autofocus: true,
focusNode: _focusNodeItemHed,
textInputAction: TextInputAction.next,
onFieldSubmitted: (v) {
debugPrint("ItemHeading submitted");
FocusScope.of(context).requestFocus(_focusNodeItemDetail);
},
decoration: InputDecoration(
labelText: "Item Heading",
hintText: "Enter item heading",
border: OutlineInputBorder(borderRadius: BorderRadius.circular(20.0)),
),
),
);
}
Widget _createItemDetailWidget() {
return Padding(
padding: const EdgeInsets.all(8.0),
child: TextFormField(
controller: _controllerItemDetail,
maxLength: 75,
focusNode: _focusNodeItemDetail,
textInputAction: TextInputAction.next,
onFieldSubmitted: (v) {
debugPrint("ItemDetail submitted");
FocusScope.of(context).requestFocus(_focusNodeItemPrice);
},
decoration: InputDecoration(
labelText: "Item Detail",
hintText: "Enter item detail",
border: OutlineInputBorder(borderRadius: BorderRadius.circular(20.0)),
),
),
);
}
class DataEntryState extends State<DataEntry> {
final TextEditingController _controllerItemHed = TextEditingController();
final TextEditingController _controllerItemDetail = TextEditingController();
final TextEditingController _controllerItemPrice = TextEditingController();
final TextEditingController _controllerSeller = TextEditingController();
final TextEditingController _controllerContactNr = TextEditingController();
final TextEditingController _controllerLocation = TextEditingController();
final FocusNode _focusNodeItemHed = FocusNode();
final FocusNode _focusNodeItemDetail = FocusNode();
final FocusNode _focusNodeItemPrice = FocusNode();
final FocusNode _focusNodeSeller = FocusNode();
final FocusNode _focusNodeContactNr = FocusNode();
final FocusNode _focusNodeLocation = FocusNode();
答案 0 :(得分:0)
尝试了许多无效的方法后,我能找到的唯一解决方案如下:
_changeFocus(BuildContext context, FocusNode focusNodeCurrent,
FocusNode focusNodeNext) {
focusNodeCurrent.unfocus();
setState(() => _focusNodeCurrent = focusNodeNext);
}
debugPrint()表明,在_changeFocus()中,unfocus()有效,而requestFocus()不起作用。
在构建中:
if (_focusNodeCurrent != null)
FocusScope.of(context).requestFocus(_focusNodeCurrent);
其他相关代码(其中一些可能是多余的):
TextFormField _createItemHeadingWidget(BuildContext context) {
FocusScope.of(context).reparentIfNeeded(_focusNodeItemHed);
return TextFormField(
controller: _controllerItemHed,
maxLength: 50,
keyboardType: TextInputType.text,
autofocus: _dataRec == null,
focusNode: _focusNodeItemHed,
textInputAction: TextInputAction.next,
onFieldSubmitted: (v) {
_changeFocus(context, _focusNodeItemHed, _focusNodeItemDetail);
},
decoration: InputDecoration(
labelText: "Item Heading",
hintText: "Enter item heading",
border: OutlineInputBorder(borderRadius: BorderRadius.circular(20.0)),
),
);
}
答案 1 :(得分:0)
使用setState()解决此问题对我来说似乎不是最佳解决方案,因此我一直进行测试。经过大量的进一步测试,主要涉及从应用程序中删除所有可能的东西之后,我最终用创建Scaffold代替了MaterialApp的创建。这解决了问题。现在,它似乎可以正常工作。所需要做的就是:
_changeFocus(BuildContext context, FocusNode focusNodeNew) {
FocusScope.of(context).requestFocus(focusNodeNew);
}
我认为最初创建MaterialApp的原因是,当我最初开始学习Flutter时,是从另一个应用程序复制了它。似乎没有必要创建MaterialApp,但是我不知道创建MaterialApp的原因,而不是仅仅创建Scaffold。
我不知道是否是颤振中的错误导致了这种现象。这可能只是使用MaterialApp的“功能”,或者可能是我滥用了MaterialApp。
答案 2 :(得分:0)
这很好地说明了颤振焦点的工作原理:https://flutter.dev/docs/cookbook/forms/focus
答案 3 :(得分:0)
对于其他为此感到挣扎的人,我只是在玩耍并制作了一个演示。
您可以将焦点切换到左侧或右侧文本字段或取消焦点。下面的代码是@Brian Oh的答案和一些新代码的组合。功能:
FocusScope.of(context).requestFocus(_nextFocusNode)
,也不必设置状态import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(home: Home(),);
}
}
class Home extends StatefulWidget {
@override
HomeState createState() => HomeState();
}
class HomeState extends State<Home> {
FocusNode currentFocusNode;
FocusNode leftFocusNode;
FocusNode rightFocusNode;
FocusNode noFocusNode;
@override
void initState() {
super.initState();
currentFocusNode = FocusNode();
leftFocusNode = FocusNode();
rightFocusNode = FocusNode();
noFocusNode = FocusNode();
}
@override
void dispose() {
//currentFocusNode.dispose();
//leftFocusNode.dispose();
//rightFocusNode.dispose();
//noFocusNode.dispose();
super.dispose();
}
changeFocus(FocusNode focusNodeNext) {
currentFocusNode.unfocus();
focusNodeNext.requestFocus();
currentFocusNode = focusNodeNext;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.fromLTRB(0, 40, 0, 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Column(
children: <Widget>[
Container( width: 50, child: TextField(
focusNode: leftFocusNode,
),),
RaisedButton(
child: Text('^ Focus ^'),
onPressed: () => changeFocus(leftFocusNode),
),
],
),
Column(
children: <Widget>[
Container( width: 50, child: TextField(
focusNode: rightFocusNode,
),),
RaisedButton(
child: Text('^ Focus ^'),
onPressed: () => changeFocus(rightFocusNode),
),
],
),
RaisedButton(
child: Text(' Cancel Focus'),
onPressed: () => changeFocus(noFocusNode),
),
],
),
),
);
}
}
我在另一个应用程序中使用了此代码,但出现了错误
在处理之后使用了FocusNode。
根据this github link,您不应调用Dispose。我已注释掉对上面的焦点节点进行的处理调用,并且错误消失了。
答案 4 :(得分:0)
使用
FocusScope.of(context).unfocus();
代替
FocusScope.of(context).requestFocus(new FocusNode());
答案 5 :(得分:0)
您可以通过在焦点更改中添加一些延迟来务实地更改焦点
FocusNode currentFocus = focusName.hasFocus? focusName : focusEmail;
FocusScope.of(context).unfocus();
Timer(const Duration(milliseconds: 1), () {
FocusScope.of(context).requestFocus(currentFocus);
});
答案 6 :(得分:0)
firstFieldFocusNode.nextFocus();
帮我搞定了
答案 7 :(得分:-1)
使用 FocusScope.of(context).nextFocus()
对我有用
我使用的自定义小部件代码
CupertinoTextFormFieldRow customTextField(
String pretext, String supportText,
TextEditingController controller, Function(String) validatorFun) {
return CupertinoTextFormFieldRow(
controller: controller,
prefix: Text(pretext),
placeholder: supportText,
validator: (val) => validatorFun(val!),
textInputAction: TextInputAction.next,
onEditingComplete: () {
FocusScope.of(context).nextFocus();
},
);
}```