当我的文本输入框的下拉按钮换成芯片平铺后,想要在手机键盘点击下一个按钮后跳转到下一个文本框,但是文本框下面有了组件(芯片组件warp,或button组件)后,就无法自动跳转。
百度后得到一个方法,但不适用于我循环数据,改装成先判断输入框个数,再通过循环向自定义的List数组里添TextEditingController()值。
官方有对应的focus小部件,但是我放到我的view里面不执行,没时间去调试了,有时间研究的可以去试下,文档里说直接用FocusNode进行管理很少见 传送门
image.png
1.百度到(flutter textInputAction.next焦点被下面的组件挡住)
class _MyFormState extends State<MyForm> {
final List<TextEditingController> _controllers =
List.generate(3, (index) => TextEditingController());
final List<FocusNode> _focusNodes =
List.generate(3, (index) => FocusNode());
@override
void dispose() {
for (var controller in _controllers) {
controller.dispose();
}
for (var focusNode in _focusNodes) {
focusNode.dispose();
}
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
children: _controllers.asMap().entries.map((entry) {
var controller = _controllers[entry.key];
var focusNode = _focusNodes[entry.key];
var isLastField = entry.key == _controllers.length - 1;
return TextField(
controller: controller,
focusNode: focusNode,
textInputAction: isLastField ? TextInputAction.done : TextInputAction.next,
onSubmitted: (value) {
if (isLastField) {
focusNode.unfocus();
} else {
FocusScope.of(context).requestFocus(_focusNodes[entry.key + 1]);
}
},
);
}).toList(),
);
}
}
2.适用于我自己
class XxxxxxView extends GetView<XxxxxxController> {
List<TextEditingController> _controllers = [];
List<FocusNode> _focusNodes = [];
bool shouldContinue = true; //控制循环变量
@override
Widget build(BuildContext context) {
return Container(
child: GetBuilder<SamplingRecordController>(builder: (ctx) {
return ListView(
children: [
_buildCyDateInput(),
_buildCyTimeInput(),
..._buildItemByConfig(context),
],
);
}),
);
}
/// 根据配置显示填写的信息
List<Widget> _buildItemByConfig(BuildContext context) {
List<Widget> list = [];
Map<String, dynamic> config =
ObjectUtil.isNotEmpty(controller.xx['xx'])
? controller.xx['xx']
: Map();
int i = 0;
int j = 1;
if(shouldContinue){ //页面热更新后会向数组重复添加一组数据,添加状态判断
config.forEach((key, configValue) {
j++;
if(xx){
}else{
_controllers.add(TextEditingController());
_focusNodes.add(FocusNode());
}
if (j > config.length) {
// 设置标志变量为false来跳出外层循环
shouldContinue = false;
return; // 跳出当前内层循环
}
});
}
config.forEach((key, configValue) {
list.add(
Column(
children: [
ListTile(
title: _buildConfigItemInput(context,configValue, i),
),
_buildConfigItemChip(context,configValue) //芯片
],
)
);
++i;
});
return list;
}
_buildConfigItemInput(BuildContext context, dynamic configValue, int i) {
var textController = _controllers[i]; //获取对应键值
var textNode = _focusNodes[i];
var isLastField = i == _controllers.length - 1; //获取是否最后一个
return GetBuilder<SamplingRecordController>(builder: (ctx) {
return GestureDetector(
onTap: () async {
},
child: Column(
children: [
Row(
children: [
Expanded(
flex: 1,
child: TextField(
controller:
textController,
enabled: enabledStatus,
autofocus: false, //必须设置为false,不然会和focusNode焦点冲突,自动关闭会上滑仍然打开
obscureText: false,
keyboardType: configValue['inputmode'] == 'number'
? TextInputType.number
: TextInputType.text,
maxLines: null,
focusNode: textNode,
onSubmitted: (value) {
if (isLastField) {
textNode.unfocus();
// FocusManager.instance.primaryFocus?.unfocus();
} else {
FocusScope.of(context).requestFocus(_focusNodes[i + 1]);
}
},
onChanged: (String value) {
},
textInputAction: isLastField ? TextInputAction.done : TextInputAction.next, //最后一个键盘展示按钮
),
),
],
),
],
)
);
});
}