Flutter开发:如何获取TableCalendar当前显示的月份名称并动态更新
实现步骤
1. 定义联动状态变量
不能给focusedDay写死固定值,需要把它改成可通过setState更新的状态变量,才能接住插件的状态同步。在State类中定义两个联动值:
- 承接日历聚焦日的DateTime变量
- 存储当前展示月份名称的字符串变量
// 可动态更新的日历聚焦日状态 DateTime _focusedDay = DateTime.now(); // 存储当前日历展示月份名称的字符串 String _currentDisplayedMonthName = ''; @override void initState() { super.initState(); // 初始化时先给月份变量赋初值,避免空值 // 方式1:用intl包的DateFormat提取月份名 _currentDisplayedMonthName = DateFormat('MMMM', 'en_US').format(_focusedDay); } // 不想引入intl包的话,可以直接内置月份列表替代上面的初始化逻辑 const List<String> _monthNames = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ]; // 初始化取值:_currentDisplayedMonthName = _monthNames[_focusedDay.month - 1];
2. 改造TableCalendar配置
在原有代码基础上做两处调整:
- 将原代码中硬编码的
focusedDay: DateTime.now()替换为定义好的状态变量_focusedDay - 新增
onPageChanged回调,这个回调会在用户左右滑动切月、点击头部箭头切月时自动触发,传入的参数就是新展示月份对应的日期值
改造后的完整日历代码:
TableCalendar( firstDay: DateTime.utc(1950, 01, 01), lastDay: DateTime.utc(2050, 01, 01), // 替换为可更新的状态变量,不要写死固定日期 focusedDay: _focusedDay, calendarFormat: CalendarFormat.month, startingDayOfWeek: StartingDayOfWeek.monday, headerStyle: HeaderStyle( formatButtonVisible: false, ), // 切月触发回调,自动更新状态 onPageChanged: (pageDate) { setState(() { // 同步更新聚焦日状态 _focusedDay = pageDate; // 提取新展示月份的全称,存入字符串变量 // 用intl的写法:_currentDisplayedMonthName = DateFormat('MMMM', 'en_US').format(pageDate); // 用内置列表的写法:_currentDisplayedMonthName = _monthNames[pageDate.month - 1]; }); }, )
关键注意点
- 如果保留原来硬编码的
focusedDay: DateTime.now()写法,无论用户怎么滑动日历,外部传入的固定值无法和插件内部的页面状态同步,永远拿不到最新的展示月份。 - 提取月份名时,传入'en_US'参数给DateFormat,可以避免受应用系统语言影响,稳定输出March、April这类要求的英文月份名,不会出现中文月份输出。
- 所有切月操作(手势滑动、头部按钮切换)都会触发
onPageChanged回调,不需要额外手动监听手势,状态更新完全自动。
内容的提问来源于stack exchange,提问作者Ayush Nanglia
相关产品推荐
相关产品推荐

