【问题标题】:Value resets in textfield when dropdown value is changed更改下拉值时,文本字段中的值会重置
【发布时间】:2018-06-19 04:52:08
【问题描述】:

只要下拉字段发生变化,甚至当您单击下拉字段时,文本字段的值都会重置。 这是代码..

list.forEach((i) {
  var textEditingController = new TextEditingController();
  textEditingControllers.add(textEditingController);
  textFields.add(
    new Column(
      children:[
      new DropdownButton<String>(
        value: _selection[i],
        items: _items.map((String item){
          return DropdownMenuItem<String>(
            value:item,
            child: new Text(item), 
            );
        }).toList(),
        onChanged: (s){
          setState(() { 
           _selection[i]=s;  
          });
        },
      ),
      new TextField(
          autocorrect: false,
          controller: textEditingController,
          textAlign: TextAlign.center,  
          keyboardType: TextInputType.number,                 
         decoration: new InputDecoration(hintText: "credit $i",hintStyle: new TextStyle(color: Colors.deepOrangeAccent[100])),
      )
      ]
    )
  );

 return textFields;
});

full code

我做错了什么吗?

交联https://github.com/flutter/flutter/issues/18592

【问题讨论】:

  • 我觉得最好把所有代码都贴出来
  • 我更新了问题
  • 我认为您需要保留 TextEditingController 实例,而不是在每个 build() 调用中重新创建它们
  • 也试过了,不行
  • @GünterZöchbauer 你是对的,我必须保留 TextEditingController 实例。我保留了列表,但没有保留所有实例。谢谢兄弟

标签: dart flutter flutter-layout


【解决方案1】:

我认为您可能错过了 @Gunter 保留 TextEditingController 实例的含义。它们应该保存到您的 State 子类中。

这是一个示例(我也稍微清理了您的代码,因为很难弄清楚发生了什么)。

class GPAcalc extends StatefulWidget {
  final int n;

  GPAcalc(this.n);

  @override
  GPAcalcstate createState() => new GPAcalcstate();
}

class GPAcalcstate extends State<GPAcalc> {
  List<String> _items = ['O', 'A+', 'A', 'B+', 'B', 'C', 'F', 'AB', 'I'].toList();
  var _selection = new List<String>();

  var _controllers;

  @override
  void initState() {
    super.initState();
    _controllers = new List.generate(widget.n, (i) => new TextEditingController());
    _selection.addAll(_items);
  }

  @override
  Widget build(BuildContext context) {
    int sogxc = 0, soc = 0;

    var textFields = new List.generate(widget.n, (i) => i)
        .map(
          (i) => new Column(
                children: [
                  new DropdownButton<String>(
                    value: _selection[i],
                    items: _items.map((String item) {
                      return DropdownMenuItem<String>(
                        value: item,
                        child: new Text(item),
                      );
                    }).toList(),
                    onChanged: (s) {
                      setState(() {
                        _selection[i] = s;
                      });
                    },
                  ),
                  new TextField(
                    autocorrect: false,
                    controller: _controllers[i],
                    textAlign: TextAlign.center,
                    keyboardType: TextInputType.number,
                    decoration: new InputDecoration(
                        hintText: "credit ${i + 1}", hintStyle: new TextStyle(color: Colors.deepOrangeAccent[100])),
                  )
                ],
              ),
        )
        .toList(growable: false);
    double res = 0.0;

    return new Scaffold(
      appBar: new AppBar(
        backgroundColor: Colors.deepOrangeAccent,
      ),
      body: new Container(
        decoration: new BoxDecoration(border: new Border.all(color: Colors.transparent, width: 5.0)),
        child: new ListView(
          children: textFields,
        ),
      ),
      floatingActionButton: new FloatingActionButton(
        tooltip: 'Calculate',
        backgroundColor: Colors.deepOrangeAccent,
        child: new Icon(Icons.keyboard_arrow_right),
        onPressed: () {
          for (int i = 0; i < widget.n; i++) {
            String r = (_controllers[i].text);
            int gp = calculate(_selection[i]);
            int cp = int.parse(r);
            int gxc = gp * cp;
            sogxc += gxc;
            soc += cp;
          }
          res = sogxc / soc;
          Navigator.of(context).push(
                new MaterialPageRoute(
                  builder: (BuildContext context) => new ScorePage(res),
                ),
              );
        },
      ),
    );
  }

  int calculate(var a) {
    if (a == "O" || a == "o") return 10;
    if (a == "A+" || a == "a+") return 9;
    if (a == "A" || a == "a") return 8;
    if (a == "B+" || a == "b+") return 7;
    if (a == "B" || a == "b") return 6;
    if (a == "C" || a == "c") return 5;
    if (a == "P" || a == "p") return 4;
    if (a == "F" || a == "f") return 0;
    if (a == "AB" || a == "ab") return 0;
    if (a == "I" || a == "i") return 0;
    return 0;
  }
}

您希望在小部件的生命周期内保留 TextEditingController 的实例 - 这样它们就可以管理文本的值。此外,当您更改下拉菜单的值时,您必须在 setState(() {}) 中进行。

您可以从小部件的State 子类访问StatefulWidget 子类中的变量。*。这比传递参数更可取。

【讨论】:

  • 哦,好吧,我明白我做错了什么,我保留了包含 TextEditingControllers 的数组,但是由于我在 build() 下的循环内创建新的 Textfields,因此数组的内容被替换为每个构建。愚蠢的错误..duh..非常感谢兄弟。
  • 如果 n 的值大于 9,您的代码会抛出此错误,RangeError (index): Invalid value: Not in range 0..8, inclusive: 9跨度>
  • 我认为那是因为只创建了 9 个默认值 - ['O', 'A+', 'A', 'B+', 'B', 'C', 'F', 'AB', 'I'].toList(); 这是您的代码遗留下来的。我不知道你到底是什么意思,所以我离开了。
  • 你照顾好
猜你喜欢
  • 1970-01-01
  • 2020-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-01
相关资源
最近更新 更多