Flutter跨页面类复制列表:无需跳转实现数据同步
方案一:将页面A的列表复制到页面B的空列表
核心思路是用ValueNotifier做轻量状态传递,页面A维护自身列表,更新时同步到ValueNotifier;页面B监听这个ValueNotifier,一旦数据变化就把新列表复制到本地空列表中。
完整代码示例
import 'package:flutter/material.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp(home: const HomePage()); } } class HomePage extends StatefulWidget { const HomePage({super.key}); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { int _currentIndex = 0; final ValueNotifier<List<String>> _pageAListNotifier = ValueNotifier([]); final List<Widget> _pages = []; @override void initState() { super.initState(); _pages.addAll([ PageA(listNotifier: _pageAListNotifier), PageB(listNotifier: _pageAListNotifier), ]); } @override void dispose() { _pageAListNotifier.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: IndexedStack(index: _currentIndex, children: _pages), bottomNavigationBar: BottomNavigationBar( currentIndex: _currentIndex, onTap: (index) => setState(() => _currentIndex = index), items: const [ BottomNavigationBarItem(icon: Icon(Icons.list), label: '页面A'), BottomNavigationBarItem(icon: Icon(Icons.view_list), label: '页面B'), ], ), ); } } // 页面A class PageA extends StatefulWidget { final ValueNotifier<List<String>> listNotifier; const PageA({super.key, required this.listNotifier}); @override State<PageA> createState() => _PageAState(); } class _PageAState extends State<PageA> { final TextEditingController _controller = TextEditingController(); final List<String> _localList = []; void _addItem() { if (_controller.text.isNotEmpty) { setState(() { _localList.add(_controller.text); widget.listNotifier.value = List.from(_localList); }); _controller.clear(); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('页面A')), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ TextField( controller: _controller, decoration: const InputDecoration(hintText: '输入内容', border: OutlineInputBorder()), ), const SizedBox(height: 16), ElevatedButton(onPressed: _addItem, child: const Text('添加到列表')), const SizedBox(height: 16), Expanded( child: ListView.builder( itemCount: _localList.length, itemBuilder: (context, index) => ListTile(title: Text(_localList[index])), ), ), ], ), ), ); } } // 页面B class PageB extends StatefulWidget { final ValueNotifier<List<String>> listNotifier; const PageB({super.key, required this.listNotifier}); @override State<PageB> createState() => _PageBState(); } class _PageBState extends State<PageB> { final List<String> _localList = []; @override void initState() { super.initState(); widget.listNotifier.addListener(() { setState(() { _localList.clear(); _localList.addAll(widget.listNotifier.value); }); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('页面B')), body: Padding( padding: const EdgeInsets.all(16.0), child: _localList.isEmpty ? const Center(child: Text('暂无数据')) : ListView.builder( itemCount: _localList.length, itemBuilder: (context, index) => ListTile(title: Text(_localList[index])), ), ), ); } }
说明
- 页面A维护自己的本地列表,每次添加数据后通过
listNotifier把完整列表传递出去 - 页面B监听
listNotifier的变化,一旦收到新数据就清空本地列表并复制新数据,实现列表同步复制的效果
方案二:输入时同时添加到两个页面的列表
核心思路是用共享数据源统一管理列表,页面A添加数据时直接更新共享列表,两个页面都基于这个共享列表渲染,实现“同时添加”的效果(本质是共享同一数据源,自动同步)。
完整代码示例
import 'package:flutter/material.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp(home: const HomePage()); } } class HomePage extends StatefulWidget { const HomePage({super.key}); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { int _currentIndex = 0; final ValueNotifier<List<String>> _sharedListNotifier = ValueNotifier([]); final List<Widget> _pages = []; @override void initState() { super.initState(); _pages.addAll([ PageA(sharedListNotifier: _sharedListNotifier), PageB(sharedListNotifier: _sharedListNotifier), ]); } @override void dispose() { _sharedListNotifier.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: IndexedStack(index: _currentIndex, children: _pages), bottomNavigationBar: BottomNavigationBar( currentIndex: _currentIndex, onTap: (index) => setState(() => _currentIndex = index), items: const [ BottomNavigationBarItem(icon: Icon(Icons.list), label: '页面A'), BottomNavigationBarItem(icon: Icon(Icons.view_list), label: '页面B'), ], ), ); } } // 页面A class PageA extends StatefulWidget { final ValueNotifier<List<String>> sharedListNotifier; const PageA({super.key, required this.sharedListNotifier}); @override State<PageA> createState() => _PageAState(); } class _PageAState extends State<PageA> { final TextEditingController _controller = TextEditingController(); void _addItem() { if (_controller.text.isNotEmpty) { final newList = List.from(widget.sharedListNotifier.value)..add(_controller.text); widget.sharedListNotifier.value = newList; _controller.clear(); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('页面A')), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ TextField( controller: _controller, decoration: const InputDecoration(hintText: '输入内容', border: OutlineInputBorder()), ), const SizedBox(height: 16), ElevatedButton(onPressed: _addItem, child: const Text('添加到共享列表')), const SizedBox(height: 16), Expanded( child: ValueListenableBuilder<List<String>>( valueListenable: widget.sharedListNotifier, builder: (context, list, child) { return ListView.builder( itemCount: list.length, itemBuilder: (context, index) => ListTile(title: Text(list[index])), ); }, ), ), ], ), ), ); } } // 页面B class PageB extends StatelessWidget { final ValueNotifier<List<String>> sharedListNotifier; const PageB({super.key, required this.sharedListNotifier}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('页面B')), body: Padding( padding: const EdgeInsets.all(16.0), child: ValueListenableBuilder<List<String>>( valueListenable: sharedListNotifier, builder: (context, list, child) { return list.isEmpty ? const Center(child: Text('暂无数据')) : ListView.builder( itemCount: list.length, itemBuilder: (context, index) => ListTile(title: Text(list[index])), ); }, ), ), ); } }
说明
- 用
_sharedListNotifier维护全局共享列表,页面A添加数据时直接更新这个列表 - 两个页面通过
ValueListenableBuilder监听共享列表的变化,自动渲染最新数据,相当于一次添加操作同时同步到两个页面的展示列表
内容的提问来源于stack exchange,提问作者Udbhav Dwivedi
相关产品推荐
相关产品推荐

