在颤动中更改动态列表的焦点

时间:2019-08-22 07:43:54

标签: flutter dart

我在flutter中有一个功能,可以打开一个带有文本字段列表的对话框。列表的大小由函数的参数确定。输入每个项目后,我想将焦点移到下一个项目。我尝试创建焦点节点列表来执行此操作,但是它不起作用。有人可以指出我在做什么错。我的代码如下所示。

Future<bool> getPositions(BuildContext context, List<String> positions) async
{
  int numPositions = positions.length ;
  final List<FocusNode> _fNodes = new List<FocusNode>.generate(numPositions, (_) => new FocusNode()) ;
  List<Widget> _widgets = new List<Widget>(numPositions) ;

  for (int i = 0 ; i < numPositions ; ++i)
  {
    int p = i+1;
    _widgets[i] = new TextField(
          style: TextStyle(fontSize: 15.0),
          autofocus: true,
          focusNode: _fNodes[i],
          controller: TextEditingController(text: positions[i]),
          textInputAction: p < numPositions ? TextInputAction.next : TextInputAction.done,
          onChanged: (value)
          {
            if (value.trim().isNotEmpty)
              positions[i] = value.trim();
          },
          onSubmitted: (value)
          {
            if (value.trim().isNotEmpty)
              positions[i] = value.trim();
            if (p >= numPositions)
              Navigator.pop(context, true);
            else
              _fieldFocusChange(context, _fNodes[i], _fNodes[p]);
          },
    );
  }

  return showDialog<bool>(
    context: context,
    barrierDismissible: false,
    builder: (context)
    {
      return AlertDialog(
        title: Text("${Config.position} names", style: TextStyle(fontSize: 15.0)),
        titlePadding: EdgeInsets.all(10.0),
        contentPadding: EdgeInsets.all(0.0),
        content: new Container(
          width: double.maxFinite,
          height: 300.0,
          child: ListView(
            padding: const EdgeInsets.all(8.0),
            children: _widgets,
          ),
        ),
        actions: <Widget>[
          new FlatButton(
              child: const Text('CANCEL'),
              onPressed: ()
              {
                Navigator.of(context).pop(false);
              }),
          new FlatButton(
              child: const Text("OK"),
              onPressed: ()
              {
                Navigator.of(context).pop(true);
              }),
        ],
      );
    },
  );
}

void _fieldFocusChange(BuildContext context, FocusNode currentFocus,FocusNode nextFocus)
{
  currentFocus.unfocus();
  FocusScope.of(context).requestFocus(nextFocus);
}

1 个答案:

答案 0 :(得分:0)

我建议添加autofocus: i == 0,否则每个节点都要求关注构建。

最小可行示例:

class Test extends StatelessWidget {

  @override
  Widget build(BuildContext context) {

    int listLength = 4;
    List<FocusNode> _focusNodes = List<FocusNode>.generate(listLength, (int index) => FocusNode());

    List<Widget> textFields = List<Widget>.generate(listLength, (int index) => TextField(
      controller: TextEditingController(),
      focusNode: _focusNodes[index],
      onSubmitted: (String value){
        if (index < listLength){
          _focusNodes[index+1].requestFocus();
        }
      },
    ));

    return Scaffold(
      body: Container(
        child: ListView(
            padding: const EdgeInsets.all(8.0),
            children: textFields
        ),
      ),
    );
  }
}