我有一个自定义的有状态小部件,当键入一个空字段时,它将在下面自动添加一个新的空字段,以便用户可以继续添加数据。
但是,当我在setState
中使用onChanged
添加新字段时,键盘将关闭,焦点将丢失在当前聚焦的字段上。
如何防止这种情况发生?
TextField(
hintText: widget.newEntryHint,
text: data[index].value,
onChanged: (val) {
setState(() {
data[index].value = val;
//if last item in list, add an extra field below
if (val.length > 0 && index == (data.length -1)) {
data.add(TextListItem(value: ""));
}
});
},
)
自定义文本字段以供参考:
class MyTextField extends StatefulWidget {
MyTextField({
this.text,
this.hintText = "",
this.onChanged,
this.onSubmitted,
this.textAlign = TextAlign.left,
this.focusNode,
this.autofocus = false,
this.obscureText = false,
this.padding = const EdgeInsets.all(0.0),
this.keyboardType = TextInputType.text,
this.canEdit = true,
this.isDarkMode = false,
this.textCapitalization = TextCapitalization.sentences,
this.key,
});
final String text;
final String hintText;
final ValueChanged<String> onChanged;
final ValueChanged<String> onSubmitted;
final TextAlign textAlign;
final FocusNode focusNode;
final bool autofocus;
final bool obscureText;
final EdgeInsets padding;
final TextInputType keyboardType;
final TextCapitalization textCapitalization;
final Key key;
final bool canEdit;
final isDarkMode;
@override
_MyTextFieldState createState() => _MyTextFieldState();
}
class _MyTextFieldState extends State<MyTextField> {
static const double textFieldPadding = 12.0;
TextEditingController editingController;
@override
void initState() {
super.initState();
editingController = TextEditingController(text: widget.text);
}
@override
Widget build(BuildContext context) {
return IgnorePointer(
ignoring: !widget.canEdit,
child: Column(
children: <Widget>[
new Padding(
padding: EdgeInsets.only(
top: textFieldPadding + widget.padding.top, bottom: textFieldPadding + widget.padding.bottom, left: widget.padding.left, right: widget.padding.right),
child: new TextField(
key: widget.key,
maxLines: null,
textCapitalization: widget.textCapitalization,
keyboardType: widget.keyboardType,
keyboardAppearance: widget.isDarkMode ? Brightness.dark : Brightness.light,
controller: editingController,
onSubmitted: widget.onSubmitted,
onChanged: widget.onChanged,
style: new TextStyle(
color: widget.isDarkMode ? Colors.white : MyColors.textBlue,
fontSize: 16.0,
fontWeight: FontWeight.w500),
autofocus: widget.autofocus,
focusNode: widget.focusNode,
textAlign: widget.textAlign,
obscureText: widget.obscureText,
decoration: new InputDecoration(
hintText: widget.hintText,
hintStyle: new TextStyle(
color: widget.isDarkMode ? MyColors.black[700] : MyColors.grey,
fontSize: 16.0,
fontWeight: FontWeight.w500),
border: InputBorder.none,
),
),
),
Divider(
color: widget.isDarkMode ? MyColors.black : MyColors.grey[150],
height: 1.0,
),
],
),
);
}
}
答案 0 :(得分:1)
我遇到了同样的问题。我发现我在容器中使用了key: UniqueKey()
。它在每个setState
上生成uniqueKey
并更新子级。检查密钥。
答案 1 :(得分:0)
我知道已经有一段时间了,也许从那以后已经解决了一些问题,但是我再也看不到您的问题了。至少以我设置窗口小部件的方式(您的data.add()
与我的fields.add()
之间的细微差别)。
List<Widget> _fields;
ScrollController controller = new ScrollController();
_buildData() {
_fields = new List();
for (int i = 0; i < 3; i++) {
_fields.add(_createMyTextField('hello$i', i));
}
}
Widget _createMyTextField(String text, int index) {
return MyTextField(
text: text,
hintText: 'hello hint$index',
onChanged: (val) {
setState(() {
//if last item in list, add an extra field below
if (val.length > 0 && index == (_fields.length-1)) {
_fields.add(_createMyTextField("", index+1));
}
});
},
);
}
@override
void initState() {
super.initState();
_buildData();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(widget.title)),
body: ListView(
controller: controller,
children: _fields.toList()
)
);
}
答案 2 :(得分:0)
我最近遇到了同样的问题。在我的情况下,问题是由树中的 Container
引起的,该树具有可选的 margin
,该 TextFormField
由子树中的焦点控制。当点击 const useArray = [Bootstrap-Vue, Vue Analytics];
useArray.forEach((item)=>{
Vue.use(item)
})
时,键盘会上下弹出并且该字段没有焦点。但是,由于焦点,容器的边距已正确更改。
通过将容器的边距改为 0 而不是 null,它解决了这个问题。它也可能适用于填充等其他属性。