You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中DropdownButton切换用户时更新TextFormField内容及实现用户信息分权限展示的问题

解决DropdownButton切换时TextFormField不更新用户信息的问题

我看了你的代码,问题出在TextFormField的initialValue属性上——它只在组件第一次初始化的时候生效,之后哪怕你通过setState更新了_currentUser,这个值也不会自动同步到输入框里。咱们来一步步解决这个问题:

核心问题分析

initialValue是一次性的初始化参数,组件构建完成后,它不会响应后续的状态变化。要实现动态更新输入框内容,你需要使用TextEditingController来控制TextFormField的文本。

具体解决方案

  1. 为可编辑字段创建对应的TextEditingController
    比如你要编辑的perfil字段,单独声明一个控制器:

    final _perfilController = TextEditingController();
    
  2. 在切换用户时更新控制器的文本
    在DropdownButton的onChanged回调里,除了更新_currentUser,还要同步更新控制器的内容:

    onChanged:(Utilizador? value) {
      setState(() {
        _currentUser = value;
        if (value != null) {
          _perfilController.text = value.perfil.toString();
        }
      });
    }
    
  3. 将控制器绑定到TextFormField
    把TextFormField的controller属性设置为你创建的控制器,去掉initialValue:

    TextFormField(
      controller: _perfilController,
      decoration: InputDecoration(
        label: Text("Perfil"),
        floatingLabelBehavior:FloatingLabelBehavior.always,
        border: OutlineInputBorder(),
      ),
    )
    
  4. 记得在组件销毁时释放控制器
    重写dispose方法,避免内存泄漏:

    @override
    void dispose() {
      _perfilController.dispose();
      super.dispose();
    }
    

修改后的完整代码

class UtilizadorPage extends StatefulWidget {
  @override
  _UtilizadorPageState createState() => new _UtilizadorPageState();
}

class _UtilizadorPageState extends State<UtilizadorPage> {
  Utilizador user = Utilizador();
  BDLocal db = BDLocal.instance;
  Utilizador? _currentUser;
  final _perfilController = TextEditingController(); // 添加控制器

  @override
  void initState(){
    super.initState();
  }

  @override
  void dispose() {
    _perfilController.dispose(); // 释放控制器
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(
          "Utilizadores",
        ),
      ),
      body: Column(
        children: [
          Row(
            crossAxisAlignment: CrossAxisAlignment.start,
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              FutureBuilder<List<Utilizador>>(
                future: user.getUtilizadores(),
                builder: (BuildContext context, AsyncSnapshot<List<Utilizador>> snapshot){
                  if (snapshot.hasError) return Text('加载用户列表出错'); // 增加错误处理
                  if (!snapshot.hasData) return CircularProgressIndicator();
                  return DropdownButton<Utilizador>(
                    alignment: Alignment.center,
                    items: snapshot.data?.map((util) => DropdownMenuItem<Utilizador>(
                      child: Text(util.nome),
                      value: util,
                    )).toList(),
                    onChanged:(Utilizador? value) {
                      setState(() {
                        _currentUser = value;
                        // 更新控制器文本
                        if (value != null) {
                          _perfilController.text = value.perfil.toString();
                        }
                      });
                    },
                    isExpanded: false,
                    value: _currentUser, // 恢复这个属性,保持选中状态
                    hint: Text('Select User'),
                  );
                }),
            ]
          ),
          SizedBox(height: 20.0),
          Row(
            children: [
              _currentUser != null ? Expanded(
                child: Column(
                  children: [
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      children: [
                        Expanded(
                          flex: 1,
                          child: Container(
                            child: InputDecorator(
                              decoration: InputDecoration(
                                labelText: "Nome",
                                floatingLabelBehavior:FloatingLabelBehavior.always,
                                border: OutlineInputBorder(),
                              ),
                              child: Text(_currentUser!.nome)
                            ),
                          ),
                        ),
                        SizedBox(width: 10.0),
                        Expanded(
                          flex: 1,
                          child: Container(
                            child: InputDecorator(
                              decoration: InputDecoration(
                                labelText: "ID na BDNuvem",
                                floatingLabelBehavior:FloatingLabelBehavior.always,
                                border: OutlineInputBorder(),
                              ),
                              child: Text(_currentUser!.id_BDNuvem.toString())
                            ),
                          ),
                        ),
                      ]),
                    SizedBox(height: 20.0),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      children: [
                        Expanded(
                          flex: 1,
                          child: TextFormField(
                            controller: _perfilController, // 使用控制器
                            decoration: InputDecoration(
                              label: Text("Perfil"),
                              floatingLabelBehavior:FloatingLabelBehavior.always,
                              border: OutlineInputBorder(),
                            ),
                          ),
                        ),
                        SizedBox(width: 10.0),
                        Expanded(
                          flex: 1,
                          child: Container(
                            child: InputDecorator(
                              decoration: InputDecoration(
                                labelText: "Numero de Colaborador",
                                floatingLabelBehavior:FloatingLabelBehavior.always,
                                border: OutlineInputBorder(),
                              ),
                              child: Text(_currentUser!.numero.toString())
                            ),
                          ),
                        ),
                      ],
                    ),
                    SizedBox(height: 20.0),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      children: [
                        Expanded(
                          flex: 1,
                          child: Container(
                            child: InputDecorator(
                              decoration: InputDecoration(
                                labelText: "Nome do Funcionario",
                                floatingLabelBehavior:FloatingLabelBehavior.always,
                                border: OutlineInputBorder(),
                              ),
                              child: Text(_currentUser!.nomeFuncionario)
                            ),
                          ),
                        ),
                      ],
                    ),
                    SizedBox(height: 20.0),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      children: [
                        Expanded(
                          flex: 1,
                          child: Container(
                            child: InputDecorator(
                              decoration: InputDecoration(
                                labelText: "Email",
                                floatingLabelBehavior:FloatingLabelBehavior.always,
                                border: OutlineInputBorder(),
                              ),
                              child: Text(_currentUser!.email)
                            ),
                          ),
                        ),
                      ],
                    ),
                    SizedBox(height: 20.0),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      children: [
                        Expanded(
                          flex: 1,
                          child: Container(
                            child: InputDecorator(
                              decoration: InputDecoration(
                                labelText: "Senha",
                                floatingLabelBehavior:FloatingLabelBehavior.always,
                                border: OutlineInputBorder(),
                              ),
                              child: Text(_currentUser!.senha)
                            ),
                          ),
                        ),
                      ],
                    ),
                    SizedBox(height: 20.0),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      children: [
                        Expanded(
                          flex: 1,
                          child: Container(
                            child: InputDecorator(
                              decoration: InputDecoration(
                                labelText: "Ultima Atualizacao",
                                floatingLabelBehavior:FloatingLabelBehavior.always,
                                border: OutlineInputBorder(),
                              ),
                              child: Text(_currentUser!.ultimaAtualizacao)
                            ),
                          ),
                        ),
                        SizedBox(width: 10.0),
                        Expanded(
                          flex: 1,
                          child: Container(
                            child: InputDecorator(
                              decoration: InputDecoration(
                                labelText: "Atualizado Por",
                                floatingLabelBehavior:FloatingLabelBehavior.always,
                                border: OutlineInputBorder(),
                              ),
                              child: Text(_currentUser!.atualizadoPor)
                            ),
                          ),
                        ),
                      ],
                    ),
                  ],
                ),
              ) : Text("No User selected"),
            ]
          )
        ],
      ),
    );
  }
}

额外提示

  • 我帮你恢复了DropdownButton的value: _currentUser属性,这样切换后下拉框会保持选中的用户,不会每次重建都回到hint状态。
  • 增加了FutureBuilder的错误处理,避免加载失败时只显示加载指示器。
  • 如果以后有更多可编辑字段,只需要为每个字段创建对应的TextEditingController,然后在onChanged里同步更新即可。

内容的提问来源于stack exchange,提问作者Martim Fernandes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 11:52:30