无需Provider,Flutter跨页面能否共享并更新响应式列表?
不使用状态管理库实现Flutter页面间List同步更新
你可以实现这个需求,核心利用Dart中List的引用类型特性,结合setState()或回调函数来同步UI,完全不需要Provider这类状态管理库。以下是具体实现方案:
基础方案(返回后同步)
这种方案在从ScreenTwo返回ScreenOne时,自动刷新ScreenOne的UI,显示更新后的List。
修改后的ScreenOne代码
class ScreenOne extends StatefulWidget { const ScreenOne({super.key}); @override State<ScreenOne> createState() => _ScreenOneState(); } class _ScreenOneState extends State<ScreenOne> { List<String> state = ['初始内容']; @override Widget build(BuildContext context) { return Column( children: [ MaterialButton( onPressed: () async { // 等待ScreenTwo页面返回,再触发UI刷新 await Navigator.pushNamed(context, '/screen-two', arguments: state); setState(() {}); // 刷新ScreenOne的UI,展示更新后的List }, child: const Text('跳转到ScreenTwo'), ), // 显示List内容,处理空列表情况 Text(state.isNotEmpty ? state.join(', ') : '列表为空'), ], ); } }
修改后的ScreenTwo代码
class ScreenTwo extends StatelessWidget { const ScreenTwo({super.key}); @override Widget build(BuildContext context) { // 获取ScreenOne传递过来的List引用(两者操作的是同一个List对象) final List<String> state = ModalRoute.of(context)!.settings.arguments as List<String>; return Column( children: [ // 同步显示当前List内容 Text(state.isNotEmpty ? state.join(', ') : '列表为空'), MaterialButton( onPressed: () { // 直接向共享的List添加新元素 state.add('新元素${state.length + 1}'); // 返回ScreenOne,触发后续的UI刷新 Navigator.pop(context); }, child: const Text('添加元素并返回'), ), ], ); } }
进阶方案(实时同步,无需返回)
如果需要在ScreenTwo中添加元素时,ScreenOne的UI立刻同步更新,不需要返回页面,可以通过传递回调函数实现:
修改后的ScreenOne跳转逻辑
MaterialButton( onPressed: () { Navigator.pushNamed( context, '/screen-two', arguments: { 'list': state, // 传递刷新回调 'onListUpdated': () => setState(() {}), }, ); }, child: const Text('跳转到ScreenTwo'), ),
修改后的ScreenTwo代码
class ScreenTwo extends StatelessWidget { const ScreenTwo({super.key}); @override Widget build(BuildContext context) { // 获取传递的参数(List和回调函数) final args = ModalRoute.of(context)!.settings.arguments as Map; final List<String> state = args['list'] as List<String>; final VoidCallback onListUpdated = args['onListUpdated'] as VoidCallback; return Column( children: [ Text(state.isNotEmpty ? state.join(', ') : '列表为空'), MaterialButton( onPressed: () { state.add('实时更新元素${state.length + 1}'); onListUpdated(); // 调用回调,立刻触发ScreenOne的UI刷新 }, child: const Text('实时添加元素'), ), MaterialButton( onPressed: () => Navigator.pop(context), child: const Text('返回ScreenOne'), ), ], ); } }
原理说明
- Dart中的List是引用类型,所以ScreenTwo接收的是ScreenOne中List的同一份引用,修改List的内容会直接作用于原始List。
- 基础方案通过
await Navigator.pushNamed()等待页面返回后调用setState(),触发ScreenOne重建UI;进阶方案则通过回调函数,在List修改时立刻通知ScreenOne刷新。
内容的提问来源于stack exchange,提问作者Dev-Siri
相关产品推荐
相关产品推荐

