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

Flutter构造函数跨页传值 pop返回上一页时值为null

问题核心原因

传值失效是几个逻辑错误直接导致的:

  • 传值方向完全写反:在AddUser页面手动实例化Register(names: saaaaa.text)创建的是一个全新的Register组件对象,和路由栈里已经存在的Register页面没有任何关联,根本不会修改原有页面的状态
  • 错误手动传递StatefulWidget参数:Register里重复定义了和Widget同名的names字段,还手动把参数传给State,破坏了Flutter State默认访问Widget属性的机制
  • 路由返回逻辑缺失:push到AddUser时没有设置await接收返回值,pop时也没有携带输入的参数,甚至AddUser的组件树里根本没加入保存按钮,逻辑根本触发不了
  • 列表生成逻辑错误:每次build都重新调用getUserModel()生成只有单个元素的新列表,根本没法累加保存多个用户的输入
修复方案

按照Flutter路由传值的标准逻辑实现即可:push跳转下一页时通过构造函数给下一页传参;下一页返回时通过Navigator.pop的第二个参数把数据带回上一页,上一页用await接收返回值后更新状态。

修正后代码

Register页面

// 补全你用到的UserModel定义
class UserModel {
  final String name;
  UserModel({required this.name});
}

class Register extends StatefulWidget {
  const Register({super.key, this.names});
  final String? names;

  @override
  State<Register> createState() => _RegisterState();
}

class _RegisterState extends State<Register> {
  // 用固定列表存储所有添加的用户,不要每次build重新生成
  List<UserModel> userList = [];

  @override
  void initState() {
    super.initState();
    // 初始如果有传入默认name,先加入列表
    if (widget.names != null && widget.names!.trim().isNotEmpty) {
      userList.add(UserModel(name: widget.names!.trim()));
    }
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        const Padding(
          padding: EdgeInsets.only(top: 10, bottom: 10),
          child: Text(
            'Seleccione una categoría:',
            textAlign: TextAlign.center,
            style: TextStyle(color: Colors.black),
          ),
        ),
        Expanded(
          child: ListView.builder(
            itemCount: userList.length,
            itemBuilder: (BuildContext ctx, int index) {
              return Container(
                margin: const EdgeInsets.all(20),
                height: 150,
                child: Stack(
                  children: [Text(userList[index].name)],
                ),
              );
            },
          ),
        ),
        FloatingActionButton(
          backgroundColor: Colors.indigo[900],
          onPressed: () async {
            // 等待AddUser页面返回结果
            final result = await Navigator.push(
              context,
              MaterialPageRoute(builder: (_) {
                return const AddUser(idUser: '');
              }),
            );
            // 收到有效输入后更新列表刷新UI
            if (result != null && result is String && result.trim().isNotEmpty) {
              setState(() {
                userList.add(UserModel(name: result.trim()));
              });
            }
          },
          child: const Icon(Icons.add, color: Colors.white),
        ),
      ],
    );
  }
}

AddUser页面

class AddUser extends StatefulWidget {
  final String? idUser;
  const AddUser({super.key, required this.idUser});

  @override
  State<AddUser> createState() => _AddUserState();
}

class _AddUserState extends State<AddUser> {
  final formKey = GlobalKey<FormState>();
  // 把无意义的控制器名改成可读的名称
  final nameController = TextEditingController();

  @override
  void dispose() {
    // 页面销毁时释放控制器,避免内存泄漏
    nameController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) => Scaffold(
        appBar: AppBar(
            automaticallyImplyLeading: false,
            title: const Text(
              'Please Enter Your Details',
              textAlign: TextAlign.center,
            )),
        body: SafeArea(
          child: ListView(
            padding: const EdgeInsets.all(16),
            children: [
              buildName(),
              const SizedBox(height: 12),
              // 原来的代码漏加保存按钮,这里补上;如果要保留自定义ButtonWidget直接替换即可
              buildButton(),
            ],
          ),
        ),
      );

  Widget buildName() => buildTitle(
        title: 'Name',
        child: TextFormField(
          controller: nameController,
          decoration: const InputDecoration(
            border: OutlineInputBorder(),
            hintText: 'Your Name',
          ),
          // 删除无效的onChanged逻辑,控制器会自动持有输入内容
        ),
      );

  Widget buildButton() => ElevatedButton(
        onPressed: () {
          final inputName = nameController.text.trim();
          if (inputName.isEmpty) {
            ScaffoldMessenger.of(context).showSnackBar(
                const SnackBar(content: Text('姓名不能为空')));
            return;
          }
          // 把输入内容作为pop的第二个参数传回上一页,不要手动new Register
          Navigator.pop(context, inputName);
        },
        child: const Text('Save'),
      );

  Widget buildTitle({
    required String title,
    required Widget child,
  }) =>
      Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          Text(
            title,
            style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 18),
          ),
          const SizedBox(height: 8),
          child,
        ],
      );
}

额外提示:不要在State里手动定义和Widget同名的参数接收构造函数值,State可以直接通过widget.xxx访问对应StatefulWidget的公开属性,手动传参很容易出现状态不同步的问题。

内容的提问来源于stack exchange,提问作者ashish rana

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 16:06:26