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

Flutter:编辑数据后DataListWidget未更新,如何实现每次显示时拉取数据?

解决Flutter Bloc/Cubit下DataListPage返回后不刷新数据的问题

问题描述

我有两个Flutter组件DataListPage和EditDataPage,采用Bloc/Cubit做状态管理。目前遇到的问题是:在EditDataPage编辑数据并调用EditDataCubit的addRecords接口完成更新后,返回DataListPage时页面仍显示旧数据;但从其他页面导航到DataListPage时数据能正常更新。DataCubit中的fetchData方法负责从API拉取数据,目前只在DataListPage的initState中调用一次。希望实现每次DataListPage显示时都重新拉取数据,求可行的解决办法。

相关代码

DataListPage

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

  @override
  State<DataListPage> createState() => _DataListPageState();
}

class _DataListPageState extends State<DataListPage> {
  @override
  void initState() {
    super.initState();
    context.read<DataCubit>().fetchData(NoParams());
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Parent(
        child: Center(
          child: SingleChildScrollView(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                BlocBuilder<DataCubit, DataState>(
                  builder: (_, state) {
                    return state.when(
                      loading: () => Column(
                        children: [
                          Skeleton(
                            height: context.height * .18,
                            width: context.width,
                          ),
                          const SpacerV(),
                        ],
                      ),
                      success: (data) => Padding(
                        padding: const EdgeInsets.all(8.0),
                        child: Column(
                          children: [
                            DataCard(
                              value: data.fetchedValue,
                              onPressed: () {
                                context.read<MainCubit>().updateIndex(8);
                                context.pushNamed(
                                  Routes.ediData.name,
                                );
                              }
                            )
                          ],
                        ),
                      ),
                      failure: (message) => const ErrorOccured(),
                      empty: () => Skeleton(
                        height: 15,
                        width: context.width,
                      ),
                    );
                  },
                )
              ],
            ),
          ),
        ),
      ),
    );
  }
}

EditDataPage

class EditDataPage extends StatefulWidget {
  const EditDataPage({super.key, required this.dataValues});

  @override
  State<EditDataPage> createState() => _EditDataPageState();
}

class _EditDataPageState extends State<EditDataPage> {
  int _editData = 0;

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(vertical: 20, horizontal: 20),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                DecimalNumberPicker(
                  minValue: 80,
                  maxValue: 120,
                  value: _editData,
                  decimalPlaces: 2,
                  onChanged: (value) {
                    setState(() {
                      _editData = value;
                    });
                  },
                ),
              ],
            ),
          Button(
           title:"Update",
            onPressed: () {
                  context.read<EditDataCubit>().addRecords(
                        Params(
                          data: _editData.toString(),
                        ),
                      );
                  context.pushReplacementNamed(Routes.dataList.name);
              }
          ),
        ],
      ),
    );
  }
}

解决方案

方法一:监听页面可见状态自动刷新

利用Flutter的WidgetsBindingObserver监听应用生命周期,当DataListPage回到前台时自动调用fetchData。

修改DataListPage的代码:

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

  @override
  State<DataListPage> createState() => _DataListPageState();
}

class _DataListPageState extends State<DataListPage> with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    context.read<DataCubit>().fetchData(NoParams());
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    // 页面回到前台时重新拉取数据
    if (state == AppLifecycleState.resumed) {
      context.read<DataCubit>().fetchData(NoParams());
    }
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  // 原build方法保持不变
  @override
  Widget build(BuildContext context) {
    // ... 原代码内容
  }
}

方法二:更新完成后主动触发刷新

等待EditDataCubit的更新操作完成后,先刷新DataCubit的数据再返回列表页,确保数据已更新。

修改EditDataPage的按钮逻辑:

Button(
  title:"Update",
  onPressed: () async {
    // 等待更新接口执行完成
    await context.read<EditDataCubit>().addRecords(
      Params(
        data: _editData.toString(),
      ),
    );
    // 主动刷新DataCubit的数据
    context.read<DataCubit>().fetchData(NoParams());
    // 返回列表页
    context.pushReplacementNamed(Routes.dataList.name);
  }
),

注意:需要确保addRecords方法返回Future,支持异步等待。

方法三:通过路由返回值触发刷新

改用pushNamed跳转,返回时传递刷新标志,让DataListPage收到后触发刷新。

  1. 修改DataListPage的跳转逻辑:
DataCard(
  value: data.fetchedValue,
  onPressed: () async {
    context.read<MainCubit>().updateIndex(8);
    // 等待页面返回结果
    final result = await context.pushNamed(Routes.ediData.name);
    // 如果返回需要刷新的标志,重新拉取数据
    if (result == true) {
      context.read<DataCubit>().fetchData(NoParams());
    }
  }
)
  1. 修改EditDataPage的按钮逻辑:
Button(
  title:"Update",
  onPressed: () async {
    await context.read<EditDataCubit>().addRecords(
      Params(
        data: _editData.toString(),
      ),
    );
    // 返回时传递刷新标志
    Navigator.pop(context, true);
  }
),

方法四:Bloc状态联动(推荐)

通过BlocListener监听EditDataCubit的状态,当更新成功时自动触发DataCubit刷新,解耦页面层逻辑。

在DataListPage的build方法中添加BlocListener:

@override
Widget build(BuildContext context) {
  return BlocListener<EditDataCubit, EditDataState>(
    listener: (context, state) {
      // 当EditDataCubit更新成功时,刷新数据
      if (state is EditDataSuccess) {
        context.read<DataCubit>().fetchData(NoParams());
      }
    },
    child: Center(
      // 原页面内容
    ),
  );
}

内容的提问来源于stack exchange,提问作者Allen P Biju

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 14:40:56