【问题标题】:ShowDialog doesn't change dropdownlistShowDialog 不会更改下拉列表
【发布时间】:2021-05-28 00:32:01
【问题描述】:

当我在 dropdownMenuItem 中更改所选项目时,我的对话框不会将其更改为我选择的项目。

我有一个下拉菜单显示客户可以选择的内容,当我选择其中一项时,所选项目不会显示在字段中,提示会保留在那里。

它以“SERVIÇO:”开头并在更改项目后保持不变。 变量获得了值,但在显示中没有改变。

  Future<void> _addObraServico(BuildContext context) async {
return showDialog(
  context: context,
  child: new Dialog(
    backgroundColor: blueSoftwar,
    child: new Column(children: <Widget>[
      Padding(
        padding: const EdgeInsets.all(8.0),
        child: Container(
          child: Text(
            "SERVIÇOS",
            style: TextStyle(
              fontSize: 20,
              color: Colors.white,
            ),
          ),
        ),
      ),
      Padding(
        padding: const EdgeInsets.all(8.0),
        child: new Theme(
          data: Theme.of(context).copyWith(
            canvasColor: orangeSoftwar,
          ),
          child: Container(
            decoration: BoxDecoration(
              border: Border.all(color: Colors.black),
              borderRadius: BorderRadius.all(Radius.circular(
                      5.0) //                 <--- border radius here
                  ),
            ),
            child: DropdownButton<String>(
              isExpanded: true,
              value: obraServicoDropDown,
              icon: const Icon(
                Icons.arrow_downward,
                color: Colors.white,
              ),
              style: const TextStyle(color: Colors.white),
              underline: SizedBox(),
              onChanged: (String newValue) {
                setState(() {
                  obraServicoDropDown = newValue;
                  print(obraServicoDropDown);
                });
              },
              items: <String>['', 'SERVICO1', 'SERVICO2', 'SERVICO3']
                  .map<DropdownMenuItem<String>>((String value) {
                return DropdownMenuItem<String>(
                  value: value,
                  child: Text(
                    value,
                    style: TextStyle(
                      color: Colors.white,
                      fontSize: 20,
                    ),
                  ),
                );
              }).toList(),
              hint: Container(
                child: Text(
                  " SERVIÇO:",
                  style: TextStyle(color: Colors.white, fontSize: 20),
                  textAlign: TextAlign.end,
                ),
              ),
            ),
          ),
        ),
      ),
      Padding(
        padding: const EdgeInsets.all(8.0),
        child: new TextField(
          style: TextStyle(color: Colors.white, fontSize: 20),
          decoration: new InputDecoration(
            focusedBorder: OutlineInputBorder(
              borderRadius: BorderRadius.all(Radius.circular(5.0)),
              borderSide: BorderSide(color: Colors.white),
            ),
            border: OutlineInputBorder(
              borderRadius: BorderRadius.all(Radius.circular(5.0)),
              borderSide: BorderSide(color: Colors.white),
            ),
            hintText: "Descrição *",
            hintStyle: TextStyle(fontSize: 20.0, color: Colors.white),
          ),
          controller: _tDescricaoObra,
        ),
      ),
      if (showAlert)
        Text(
          "Preencha os campos",
          style: TextStyle(fontSize: 20, color: Colors.red),
        ),
      new FlatButton(
        color: Colors.orange,
        child: new Text(
          "CADASTRAR",
          style: TextStyle(color: Colors.white),
        ),
        onPressed: () {
          if (obraServicoDropDown == null || _tDescricaoObra.text.isEmpty) {
            showAlert = true;
          } else {
            ServicoObra servico = new ServicoObra();
            servico.servico = obraServicoDropDown;
            servico.descricao = _tDescricaoObra.text;
            setState(() {
              servicos.add(servico);
            });
            obraServicoDropDown = null;
            _tDescricaoObra.clear();
            showAlert = false;
            Navigator.pop(context);
          }
        },
      ),
    ]),
  ),
);

}

【问题讨论】:

    标签: flutter dart showdialog


    【解决方案1】:

    从showDialog调用setState会改变widget的状态,但不会重建dialog,因为Flutter不会仅仅因为我们改变了调用dialog的widget的状态就认为dialog的状态会改变。

    解决这个问题的方法是使对话框有状态;通过 StatefulBuilder 或作为 StatefulWidget。无论哪种情况,现在更改对话框中的下拉状态只会在对话框中更改它;所以我们还需要来自主小部件的回调来改变那里的状态。下面演示 sn-p。

    class DialogDropdown extends StatefulWidget {
      const DialogDropdown({Key? key}) : super(key: key);
    
      @override
      State<DialogDropdown> createState() => _DialogDropdownState();
    }
    
    class _DialogDropdownState extends State<DialogDropdown> {
      String? _grade;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            centerTitle: true,
            title: const Text("Dialog Dropdown"),
          ),
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                Text(
                  _grade ?? "Unknown",
                  style: Theme.of(context).textTheme.headline4,
                ),
                const Text(
                  'Grade',
                ),
              ],
            ),
          ),
          floatingActionButton: FloatingActionButton(
            onPressed: () {
              showDialog(
                context: context,
                builder: (context) => gradeDialog(),
              );
            },
            tooltip: 'Change Grade',
            child: const Icon(Icons.arrow_upward),
          ),
        );
      }
    
      void _changeGrade(_newGrade) {
        setState(
          () {
            _grade = _newGrade;
          },
        );
      }
    
      StatefulBuilder gradeDialog() {
        return StatefulBuilder(
          builder: (context, _setter) {
            return Dialog(
              child: Padding(
                padding: const EdgeInsets.all(15),
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Text(_grade ?? "Unknown"),
                    const SizedBox(height: 30),
                    DropdownButton<String>(
                      value: _grade,
                      onChanged: (String? _newGrade) {
                        _setter(
                          () {
                            _grade = _newGrade!;
                          },
                        );
                        _changeGrade(_newGrade);
                      },
                      items: ["A", "B"].map<DropdownMenuItem<String>>(
                        (String value) {
                          return DropdownMenuItem<String>(
                            value: value,
                            child: Text(value),
                          );
                        },
                      ).toList(),
                    ),
                  ],
                ),
              ),
            );
          },
        );
      }
    }
    

    【讨论】:

      【解决方案2】:

      obraServicoDropDown 在哪里被初始化?我怀疑obraServicoDropDown 的初始化发生在有状态小部件的小部件build 函数中。因此,即使在setState 将其更改为正确状态后,obraServicoDropDown 的重新初始化也会恢复原始状态。

      【讨论】:

      • 它不在构建中,我只是像这样声明它 String obraServicoDropDown;它第一次收到值是当我更改下拉列表时
      猜你喜欢
      • 1970-01-01
      • 2018-01-17
      • 1970-01-01
      • 1970-01-01
      • 2020-01-23
      • 2011-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多