简体   繁体   English

ShowDialog 不会更改下拉列表

[英]ShowDialog doesn't change dropdownlist

When I change the chosen item in dropdownMenuItem, my dialog doesn't change it to what I selected.当我在 dropdownMenuItem 中更改所选项目时,我的对话框不会将其更改为我选择的项目。

I have a dropdown that shows what the client can select, when I select one of them the selected item doesn't display in the field, the hint keeps there.我有一个下拉菜单显示客户端可以做什么 select,当我 select 其中一个项目未显示在字段中时,提示保留在那里。

it starts with "SERVIÇO:" and keeps like that after changing the item.它以“SERVIÇO:”开头,并在更改项目后保持不变。 the variable gets the value but it doesn't change in display.变量获取值,但在显示中没有改变。

  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);
          }
        },
      ),
    ]),
  ),
);

} }

Calling setState from showDialog changes the state of the widget, but it does not rebuild the dialog, because Flutter does not consider the state of the dialog to be changed just because we changed the state of the widget that called the dialog. Calling setState from showDialog changes the state of the widget, but it does not rebuild the dialog, because Flutter does not consider the state of the dialog to be changed just because we changed the state of the widget that called the dialog.

对话框下拉菜单 - 问题

The way to fix this is to make the dialog stateful;解决这个问题的方法是使对话框有状态; either through StatefulBuilder or as a StatefulWidget.通过 StatefulBuilder 或作为 StatefulWidget。 In either case, now changing the dropdown state in the dialog will only change it in the dialog;无论哪种情况,现在在对话框中更改下拉菜单 state 只会在对话框中更改它; so we also need a callback from the main widget to change the state there as well.所以我们还需要来自主小部件的回调来更改 state 那里。 Demo snippet below.下面的演示片段。

在此处输入图像描述

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(),
                ),
              ],
            ),
          ),
        );
      },
    );
  }
}

Where is obraServicoDropDown being initialized? obraServicoDropDown在哪里初始化? I suspect that the initialization of obraServicoDropDown is happening within the Widget's build function of the Stateful Widget.我怀疑obraServicoDropDown的初始化发生在有状态小部件的小部件build function 中。 Hence, even after setState changes it to the correct state, the re-initialization of obraServicoDropDown brings back the original state.因此,即使在setState将其更改为正确的 state 之后,重新初始化obraServicoDropDown恢复原来的 state。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM