更改下拉值时文本字段中的值重置

Value resets in textfield when dropdown value is changed

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

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

我认为您可能已经错过了@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(() {}).

中进行

并且您可以从位于 widget.* 的 State 子类访问 StatefulWidget 子类中的变量。这比传递参数更可取。