Flutter求助:无法实现Custom页与Calendar页一致的Schedule列表生成功能
解决Flutter跨页面日程列表同步问题
1. 定义统一的日程数据结构
先创建一个数据类存储日程信息,同时标记来源(区分Calendar/Custom),方便后续拆分独立列表:
class ScheduleItem { final String source; // 标记来自Calendar或Custom final DateTime date; final TimeOfDay time; ScheduleItem({required this.source, required this.date, required this.time}); }
2. 用状态管理实现跨页面数据共享
用Flutter自带的ChangeNotifier+Provider实现轻量状态共享,无需额外依赖:
import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; class ScheduleProvider extends ChangeNotifier { final List<ScheduleItem> _scheduleItems = []; List<ScheduleItem> get items => _scheduleItems; void addScheduleItem(ScheduleItem item) { _scheduleItems.add(item); notifyListeners(); // 通知所有监听页面刷新 } }
在main.dart中用ChangeNotifierProvider包裹根组件,让三个页面都能访问该状态:
void main() { runApp( ChangeNotifierProvider( create: (context) => ScheduleProvider(), child: const MyApp(), ), ); }
3. 修改Calendar和Custom页的提交逻辑
在两个页面选择完日期时间后,点击按钮时调用状态管理类的添加方法:
Calendar页提交示例
// 假设已获取选中的selectedDate和selectedTime TextButton( onPressed: () { final scheduleProvider = Provider.of<ScheduleProvider>(context, listen: false); scheduleProvider.addScheduleItem( ScheduleItem( source: 'Calendar', date: selectedDate, time: selectedTime, ), ); Navigator.pop(context); // 返回Schedule页 }, child: const Text('添加到日程'), )
Custom页提交示例
仅需修改source字段,其余逻辑一致:
TextButton( onPressed: () { final scheduleProvider = Provider.of<ScheduleProvider>(context, listen: false); scheduleProvider.addScheduleItem( ScheduleItem( source: 'Custom', date: selectedCustomDate, time: selectedCustomTime, ), ); Navigator.pop(context); }, child: const Text('添加到日程'), )
4. 在Schedule页实现独立列表视图
用Consumer监听状态变化,将日程按来源拆分为两个独立列表:
class SchedulePage extends StatelessWidget { const SchedulePage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Schedule'), actions: [ IconButton( icon: const Icon(Icons.calendar_today), onPressed: () { Navigator.push( context, MaterialPageRoute(builder: (context) => const CalendarCustomTogglePage()), ); }, ), ], ), body: Consumer<ScheduleProvider>( builder: (context, provider, child) { // 按来源拆分日程列表 final calendarItems = provider.items.where((item) => item.source == 'Calendar').toList(); final customItems = provider.items.where((item) => item.source == 'Custom').toList(); return Column( children: [ // Calendar日程列表 Expanded( child: Column( children: [ const Padding( padding: EdgeInsets.all(8.0), child: Text('Calendar 日程', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), ), calendarItems.isEmpty ? const Expanded(child: Center(child: Text('暂无Calendar日程'))) : Expanded( child: ListView.builder( itemCount: calendarItems.length, itemBuilder: (context, index) { final item = calendarItems[index]; return ListTile( title: Text('${item.date.year}-${item.date.month}-${item.date.day}'), subtitle: Text('${item.time.hour}:${item.time.minute}'), ); }, ), ), ], ), ), const Divider(height: 1), // Custom日程列表 Expanded( child: Column( children: [ const Padding( padding: EdgeInsets.all(8.0), child: Text('Custom 日程', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), ), customItems.isEmpty ? const Expanded(child: Center(child: Text('暂无Custom日程'))) : Expanded( child: ListView.builder( itemCount: customItems.length, itemBuilder: (context, index) { final item = customItems[index]; return ListTile( title: Text('${item.date.year}-${item.date.month}-${item.date.day}'), subtitle: Text('${item.time.hour}:${item.time.minute}'), ); }, ), ), ], ), ), ], ); }, ), ); } }
5. 实现Calendar与Custom的切换页
用TabBar实现页面切换,示例代码:
class CalendarCustomTogglePage extends StatefulWidget { const CalendarCustomTogglePage({super.key}); @override State<CalendarCustomTogglePage> createState() => _CalendarCustomTogglePageState(); } class _CalendarCustomTogglePageState extends State<CalendarCustomTogglePage> { int _currentTab = 0; final List<Widget> _pages = const [CalendarPage(), CustomPage()]; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('选择日程类型'), bottom: TabBar( tabs: const [Tab(text: 'Calendar'), Tab(text: 'Custom')], onTap: (index) => setState(() => _currentTab = index), ), ), body: _pages[_currentTab], ); } }
内容的提问来源于stack exchange,提问作者Amal Prasad
相关产品推荐
相关产品推荐

