【问题标题】:TextFormField controllers in ListviewListview 中的 TextFormField 控制器
【发布时间】:2021-09-01 12:27:31
【问题描述】:

在下面的代码库中,我有一个 List 和三个 TextFormField。单击按钮后,我在列表中添加了更多 TextFormField。我能够从这个 stackoverflow 博客 (link) 中实现 UI 部分。

不确定我们如何在颤振列表中跟踪控制器。

需要像数组一样使用列表视图中的所有 editText 字段进行发布 API 调用

下面是代码

class CreateVariantMobilePortrait extends StatefulWidget {
  @override
  _CreateVariantMobilePortraitState createState() =>
      _CreateVariantMobilePortraitState();
}

class _CreateVariantMobilePortraitState
    extends State<CreateVariantMobilePortrait> {
  final _scaffoldKey = GlobalKey<ScaffoldState>();
  final _formKey = GlobalKey<FormState>();
  int _count = 1;

  @override
  Widget build(BuildContext context) {
    var scrWidth = MediaQuery.of(context).size.width;
    var scrHeight = MediaQuery.of(context).size.height;
    return Scaffold(
      key: _scaffoldKey,
      drawer: AppDrawer(),
      body: Row(
        children: [
          Align(
            alignment: Alignment.topCenter,
            child: Padding(
              padding: const EdgeInsets.all(10),
              child: IconButton(
                  icon: Icon(Icons.menu, size: 30),
                  onPressed: () {
                    _scaffoldKey.currentState.openDrawer();
                  }),
            ),
          ),
          Flexible(
            child: SingleChildScrollView(
              physics: BouncingScrollPhysics(),
              child: _buildForm(scrWidth, scrHeight),
            ),
          ),
        ],
      ),
    );
  }

  Form _buildForm(double scrWidth, double height) {
    List<Widget> _testCases =
        new List.generate(_count, (int i) => new CreateTestCase());
    void _addNewTestCaseColumn() {
      setState(() {
        _count = _count + 1;
      });
    }

    return Form(
      key: _formKey,
      child: Column(
        children: <Widget>[
          Align(
            alignment: Alignment.centerLeft,
            child: Padding(
              padding: const EdgeInsets.only(top: 70),
              child: Text(
                Strings.create_variant_title,
                style: TextStyle(
                  fontFamily: 'Cardo',
                  fontSize: 35,
                  color: Color(0xff0C2551),
                  fontWeight: FontWeight.w900,
                ),
              ),
            ),
          ),
          SizedBox(
            height: 50,
          ),
          Column(
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.fromLTRB(0, 0, 40, 15),
                child: TextFormField(
                  autovalidateMode: AutovalidateMode.onUserInteraction,
                  validator: (String value) {
                    if (value.isEmpty) {
                      return "Variant Name cannot be empty";
                    } else if (value.length < 4) {
                      return "Variant Name must be at least 3 characters long";
                    }
                    return null;
                  },
                  style: TextStyle(fontSize: 20),
                  decoration: InputDecoration(
                      labelText: Strings.variant_name,
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(20.0),
                      )),
                ),
              )
            ],
          ),
          SizedBox(
            height: 30,
          ),
          Column(
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.fromLTRB(0, 0, 40, 15),
                child: TextFormField(
                  autovalidateMode: AutovalidateMode.onUserInteraction,
                  validator: (String value) {
                    if (value.isEmpty) {
                      return "Environment cannot be empty";
                    }
                    return null;
                  },
                  style: TextStyle(fontSize: 20),
                  keyboardType: TextInputType.emailAddress,
                  decoration: InputDecoration(
                      labelText: Strings.variant_environment,
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(20.0),
                      )),
                ),
              )
            ],
          ),
          SizedBox(
            height: 30,
          ),
          Column(
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.fromLTRB(0, 0, 40, 15),
                child: TextFormField(
                  maxLines: null,
                  autovalidateMode: AutovalidateMode.onUserInteraction,
                  // controller: zipCodeController,
                  validator: (String value) {
                    if (value.isEmpty) {
                      return "Please enter the variant description";
                    }
                    return null;
                  },
                  style: TextStyle(fontSize: 20),
                  keyboardType: TextInputType.number,
                  decoration: InputDecoration(
                      labelText: Strings.variant_description,
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(20.0),
                      )),
                ),
              )
            ],
          ),
          SizedBox(
            height: 30,
          ),
          Align(
            alignment: Alignment.centerLeft,
            child: Padding(
              padding: const EdgeInsets.fromLTRB(0, 0, 40, 15),
              child: Text(
                Strings.test_cases,
                style: TextStyle(
                  fontFamily: 'Cardo',
                  fontSize: 20,
                  color: Color(0xff0C2551),
                  fontWeight: FontWeight.w900,
                ),
              ),
            ),
          ),
          ConstrainedBox(
            constraints: BoxConstraints(maxHeight: 5000.0),
            child: new ListView(
              children: _testCases,
              scrollDirection: Axis.vertical,
              shrinkWrap: true,
              physics: NeverScrollableScrollPhysics(),
            ),
          ),
          Column(
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.fromLTRB(0, 0, 40, 15),
                child: new TextButton(
                  onPressed: _addNewTestCaseColumn,
                  child: Column(
                    children: <Widget>[
                      Icon(Icons.add),
                      Text("Add another Test case")
                    ],
                  ),
                ),
              )
            ],
          ),
          Column(
            children: <Widget>[
              Container(
                margin: EdgeInsets.only(right: 30),
                width: scrWidth * 0.85,
                height: 75,
                child: ElevatedButton(
                  onPressed: () {},
                  style: ElevatedButton.styleFrom(
                      primary: Color(0xff0962ff),
                      textStyle: TextStyle(
                        fontSize: 20,
                        color: Colors.white,
                        fontWeight: FontWeight.bold,
                      ),
                      shape: new RoundedRectangleBorder(
                          borderRadius: new BorderRadius.circular(15))),
                  child: Text("Create Variant"),
                ),
              ),
            ],
          ),
          SizedBox(
            height: 50,
          ),
        ],
      ),
    );
  }
}

下面是列表项的代码

class CreateTestCase extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => new _CreateTestCase();
}

class _CreateTestCase extends State<CreateTestCase> {
  @override
  Widget build(BuildContext context) {
    return _buildCreateTestCaseForm();
  }

  Form _buildCreateTestCaseForm() {
    return Form(
      child: Column(
        children: <Widget>[
          Column(
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.fromLTRB(0, 0, 40, 15),
                child: TextFormField(
                  maxLines: null,
                  autovalidateMode: AutovalidateMode.onUserInteraction,
                  validator: (String value) {
                    if (value.isEmpty) {
                      return "Test case name cannot be empty";
                    }
                    return null;
                  },
                  style: TextStyle(fontSize: 20),
                  decoration: InputDecoration(
                      labelText: Strings.testcase_name,
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(20.0),
                      )),
                ),
              )
            ],
          ),
          SizedBox(
            height: 30,
          ),
          Column(
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.fromLTRB(0, 0, 40, 15),
                child: TextFormField(
                  autovalidateMode: AutovalidateMode.onUserInteraction,
                  validator: (String value) {
                    if (value.isEmpty) {
                      return "Please enter Test case Description";
                    }
                    return null;
                  },
                  style: TextStyle(fontSize: 20),
                  keyboardType: TextInputType.number,
                  decoration: InputDecoration(
                      labelText: Strings.testcase_description,
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(20.0),
                      )),
                ),
              )
            ],
          ),
          SizedBox(
            height: 30,
          ),
          Column(
            children: <Widget>[
              Padding(
                padding: const EdgeInsets.fromLTRB(0, 0, 40, 15),
                child: TextFormField(
                  autovalidateMode: AutovalidateMode.onUserInteraction,
                  // controller: zipCodeController,
                  validator: (String value) {
                    if (value.isEmpty) {
                      return "Please enter Test conditions";
                    }
                    return null;
                  },
                  style: TextStyle(fontSize: 20),
                  keyboardType: TextInputType.number,
                  decoration: InputDecoration(
                      labelText: Strings.test_data_conditions,
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(20.0),
                      )),
                ),
              )
            ],
          ),
          SizedBox(
            height: 30,
          ),
          Divider(
            height: 20,
            endIndent: 50,
          ),
          SizedBox(
            height: 30,
          ),
        ],
      ),
    );
  }
}

【问题讨论】:

    标签: flutter dart flutter-listview


    【解决方案1】:

    您可以在创建测试用例时生成文本编辑控制器列表:

    
    List<TextEditingController> controllers = [];
    List<Widget> _testCases = new List.generate(_count, (int i) {
        final controller = TextEditingController();
        controllers.add(controller); 
        return CreateTestCase(controller: controller); 
    });
    
    

    您必须将controller 添加为CreateTestCase 的参数。 controllers 可能必须在方法之外定义为状态的属性。

    这还是有点乱,好像你从列表中删除了一个项目,它的行为可能会很奇怪。

    这是我能很快为您的代码想到的最简单的解决方案,但我会考虑进一步分离小部件并添加更复杂的状态管理解决方案而不是 setState;

    【讨论】:

    • 不知何故它不起作用,可能是我做错了什么。但我想知道一件事,在我的情况下,每个项目都有 3 TextFormFields 是否能够根据索引值进行跟踪?
    • 嗨,何塞,我尝试了您推荐的上述更改。它对我不起作用
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-23
    • 1970-01-01
    • 1970-01-01
    • 2020-12-13
    • 2018-03-30
    • 2018-06-12
    • 2020-06-15
    相关资源
    最近更新 更多