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

Flutter桌面端setState无法更新屏幕下拉框选中值

问题根因

所有需要随组件生命周期保留的状态变量、表单Key、下拉选项列表都被写在了build方法内部。setState的本质是触发组件重新执行build方法重绘界面,每次重绘时这些写在build里的变量都会被重新初始化,_dropdownvalue会被直接重置为初始值"Global admin",导致选中操作的修改被覆盖,界面上看不到更新效果。

修复方案
  • 将_formKey、_dropdownvalue、_items三个变量从build方法内部移到_LoginViewState类的成员属性位置,保证变量不会在每次重绘时被重置。
  • 修正下拉选项构造时的变量名冲突问题:原代码中map方法的入参命名和外层列表_items重名,容易引发值引用混乱,建议将入参名改为不冲突的命名。
修复后完整代码
import 'package:demo_app_admin/Custom/custom_Font.dart';
import 'package:flutter/material.dart';
import '/Custom/Custom_Raised_Bottun.dart';
import '/Custom/Header.dart';
import '/Custom/inputField.dart';

class LoginView extends StatefulWidget {
  @override
  _LoginViewState createState() => _LoginViewState();
}

class _LoginViewState extends State<LoginView> {
  // 所有持久化状态移到build方法外,作为State类成员
  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
  String _dropdownvalue = "Global admin";
  final List<String> _items = <String>["Global admin", "Institution admin"];

  @override
  Widget build(BuildContext context) {
    final isKeyboard = MediaQuery.of(context).viewInsets.bottom != 0;
    return Scaffold(
      body: Container(
        width: double.infinity,
        decoration: BoxDecoration(
          gradient: LinearGradient(begin: Alignment.topCenter, colors: [
            Colors.teal[700]!,
            Colors.teal[200]!,
            Colors.teal[400]!
          ]),
        ),
        child: Column(
          children: <Widget>[
            const SizedBox(height: 80),
            if (!isKeyboard)
              Header(
                padding: const EdgeInsets.all(20),
                crossAxisAlignment: CrossAxisAlignment.start,
                head: "Welcome",
                headTextStyle:
                    const TextStyle(color: Colors.white, fontSize: 40),
                sizedBoxHeight: 10,
                subtitle: "Sign In to Your Admin Account",
                subtitleTextStyle:
                    const TextStyle(color: Colors.white, fontSize: 18),
              ),
            Expanded(
                child: Container(
              decoration: const BoxDecoration(
                  color: Colors.white,
                  borderRadius: BorderRadius.only(
                    topLeft: Radius.circular(60),
                    topRight: Radius.circular(60),
                  )),
              child: Padding(
                padding: const EdgeInsets.all(30),
                child: SingleChildScrollView(
                  reverse: true,
                  padding: EdgeInsets.all(32),
                  child: Form(
                    key: _formKey,
                    child: Column(
                      children: <Widget>[
                        const SizedBox(height: 40),
                        Container(
                          decoration: BoxDecoration(
                              color: Colors.white,
                              borderRadius: BorderRadius.circular(10)),
                          child: Column(
                            children: <Widget>[
                              InputField(
                                labelText: 'Email',
                                padding: EdgeInsets.all(10),
                                borderSide: BorderSide(color: Colors.grey),
                                hintText: "Enter your email",
                                color: Colors.grey,
                                inputBorder: InputBorder.none,
                                obscureText: false,
                                enableSuggestion: true,
                                autoCorrect: true,
                                onSaved: (value) {},
                                validator: (value) {
                                  if (value == null) {
                                    print("ERROR");
                                  }
                                },
                              ),
                              InputField(
                                labelText: 'Password',
                                padding: EdgeInsets.all(10),
                                borderSide: BorderSide(color: Colors.grey),
                                hintText: "Enter your password",
                                color: Colors.grey,
                                inputBorder: InputBorder.none,
                                obscureText: true,
                                enableSuggestion: false,
                                autoCorrect: false,
                                onSaved: (value) {},
                                validator: (value) {
                                  if (value == null) {
                                    print("ERROR");
                                  }
                                },
                              ),
                            ],
                          ),
                        ),
                        const SizedBox(height: 40),
                        DropdownButton<String>(
                            value: _dropdownvalue,
                            icon: Icon(Icons.keyboard_arrow_down),
                            // 修正入参命名,避免和外层列表重名
                            items: _items.map((String item) {
                              return DropdownMenuItem<String>(
                                value: item,
                                child: CustomFont(text: item),
                              );
                            }).toList(),
                            onChanged: (value) {
                              setState(() => _dropdownvalue = value!);
                            }),
                        const SizedBox(height: 40),
                        CustomRaisedButton(
                            width: 200,
                            height: 50.0,
                            margin: const EdgeInsets.symmetric(horizontal: 50),
                            color: Colors.teal.shade500,
                            borderRadius: BorderRadius.circular(10),
                            text: "LOGIN",
                            textColor: Colors.white,
                            fontSize: 17,
                            fontWeight: FontWeight.bold,
                            function: () {}),
                        const SizedBox(height: 10),
                      ],
                    ),
                  ),
                ),
              ),
            ))
          ],
        ),
      ),
    );
  }
}

内容的提问来源于stack exchange,提问作者Mohammad Al-Zoubi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 21:21:39