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

自定义Dialog中setState函数失效问题求助

问题原因

你遇到的问题是:添加客户后,虽然数据已经加入customersList,但主页面的列表没有刷新。核心原因是Dialog里调用的setState()只更新Dialog自身的状态,不会触发主页面MyAppState的重建,所以ListView.builder不会重新渲染新数据。

解决方案:通过回调通知主页面刷新

我们给Dialog添加一个回调函数,当客户添加完成后,让主页面调用自己的setState()来刷新列表。

1. 修改自定义Dialog代码

import 'package:flutter/material.dart';
import 'package:untitled66/customers.dart';

class Dialog1 extends StatefulWidget {
  // 添加回调函数,用于通知主页面刷新
  final VoidCallback onCustomerAdded;
  const Dialog1({super.key, required this.onCustomerAdded});

  @override
  State<StatefulWidget> createState() {
    return dialog1State();
  }
}

class dialog1State extends State<Dialog1> {
  final TextEditingController customerNamecontr = TextEditingController();
  final TextEditingController itemNamecontr = TextEditingController();
  final TextEditingController pricecontr = TextEditingController();
  final TextEditingController profitcontr = TextEditingController();
  final TextEditingController periodcontr = TextEditingController();

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: const Text('Add customer'),
      content: Form(
          child: ListView(
        shrinkWrap: true, // 避免ListView高度溢出问题
        children: [
          const Text("Customer's name:"),
          TextFormField(controller: customerNamecontr),
          const Text("Item's name:"),
          TextFormField(controller: itemNamecontr),
          const Text("Price:"),
          TextFormField(
            controller: pricecontr,
            keyboardType: TextInputType.number, // 适配数字输入
          ),
          const Text("Profit:"),
          TextFormField(
            controller: profitcontr,
            keyboardType: TextInputType.number,
          ),
          const Text("Period:"),
          TextFormField(
            controller: periodcontr,
            keyboardType: TextInputType.number,
          ),
        ],
      )),
      actions: [
        TextButton(
            onPressed: () {
              double? price = double.tryParse(pricecontr.text);
              int? profit = int.tryParse(profitcontr.text);
              int? period = int.tryParse(periodcontr.text);

              // 增加输入合法性判断,避免空值报错
              if (price != null &&
                  profit != null &&
                  period != null &&
                  customerNamecontr.text.isNotEmpty &&
                  itemNamecontr.text.isNotEmpty) {
                customersList.add(Customers(
                  name: customerNamecontr.text,
                  itemName: itemNamecontr.text,
                  price: price,
                  profit: profit,
                  period: period,
                  key: UniqueKey(),
                ));
                // 调用回调通知主页面刷新
                widget.onCustomerAdded();
                Navigator.of(context).pop();
              }
            },
            child: const Text('Add'))
      ],
    );
  }
}

2. 修改主页面代码

import 'package:flutter/material.dart';
import 'package:untitled66/custom_dialog.dart';
import 'package:untitled66/customers.dart';

List<Customers> customersList = [
  Customers(
    name: 'munsef',
    itemName: 'mobile',
    price: 100,
    profit: 30,
    period: 12,
    key: UniqueKey(),
  ),
];

void main() {
  runApp(const MaterialApp(
    home: MyApp(),
  ));
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => MyAppState();
}

class MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
          floatingActionButton: FloatingActionButton(
              child: const Icon(Icons.add),
              onPressed: () {
                showDialog(
                    context: context,
                    builder: (context) {
                      return Dialog1(
                        // 传入回调,触发主页面刷新
                        onCustomerAdded: () {
                          setState(() {});
                        },
                      );
                    });
              }),
          appBar: AppBar(
            title: const Text('List of Items'),
            backgroundColor: Colors.lightBlue,
          ),
          body: ListView.builder(
              itemCount: customersList.length,
              itemBuilder: (context, index) {
                return InkWell(
                  child: Card(
                    child: customersList[index],
                  ),
                  onLongPress: () {
                    // 把删除操作包裹在setState里,代码更规范
                    setState(() {
                      customersList.removeAt(index);
                    });
                  },
                );
              })),
    );
  }
}
额外优化建议
  • 把全局的customersList移到MyAppState内部,避免全局变量,状态管理更清晰。
  • 可以给输入框添加表单验证逻辑,提升用户体验。

内容的提问来源于stack exchange,提问作者munsef khasawneh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 06:25:13