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收到后触发刷新。
- 修改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()); } } )
- 修改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
相关产品推荐
相关产品推荐

