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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 12:04:52