Flutter健身追踪应用中基于日历的本地日期数据管理咨询
Flutter本地日历式健身数据追踪实现指南
一、选择日历UI组件
直接用table_calendar包,这是Flutter生态里最成熟的日历组件,支持日期选择、自定义样式,完全适配需求。
- 添加依赖到
pubspec.yaml:dependencies: table_calendar: ^3.0.0 - 基础使用示例:
import 'package:table_calendar/table_calendar.dart'; class FitnessCalendarPage extends StatefulWidget { @override _FitnessCalendarPageState createState() => _FitnessCalendarPageState(); } class _FitnessCalendarPageState extends State<FitnessCalendarPage> { DateTime _selectedDay = DateTime.now(); DateTime _focusedDay = DateTime.now(); FitnessRecord? _currentRecord; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('健身日历')), body: Column( children: [ TableCalendar( firstDay: DateTime.utc(2020, 1, 1), lastDay: DateTime.utc(2030, 12, 31), focusedDay: _focusedDay, selectedDayPredicate: (day) => isSameDay(_selectedDay, day), onDaySelected: (selectedDay, focusedDay) { setState(() { _selectedDay = selectedDay; _focusedDay = focusedDay; }); _loadFitnessData(selectedDay); }, ), Expanded(child: _buildFitnessDataDisplay()), ], ), ); } void _loadFitnessData(DateTime day) { // 后续实现本地数据查询 } Widget _buildFitnessDataDisplay() { // 后续实现数据展示UI return Center(child: Text('选择日期查看健身数据')); } }
二、本地数据存储方案
用hive轻量级NoSQL本地数据库,比shared_preferences更适合存储带日期的结构化健身数据。
- 添加依赖:
dependencies: hive: ^2.0.0 hive_flutter: ^1.1.0 dev_dependencies: hive_generator: ^1.1.0 build_runner: ^2.0.0 - 初始化Hive(在
main.dart中):import 'package:hive_flutter/hive_flutter.dart'; import 'fitness_record.dart'; void main() async { await Hive.initFlutter(); Hive.registerAdapter(FitnessRecordAdapter()); await Hive.openBox<FitnessRecord>('fitness_records'); runApp(MyApp()); } - 定义健身数据模型:
创建fitness_record.dart:
运行命令生成适配器:import 'package:hive/hive.dart'; part 'fitness_record.g.dart'; @HiveType(typeId: 0) class FitnessRecord extends HiveObject { @HiveField(0) DateTime date; @HiveField(1) int caloriesBurned; @HiveField(2) List<String> exercises; FitnessRecord({required this.date, required this.caloriesBurned, required this.exercises}); }flutter packages pub run build_runner build - 核心数据操作方法:
// 保存当日健身数据(覆盖同日期旧数据) void saveFitnessData(FitnessRecord record) async { final box = Hive.box<FitnessRecord>('fitness_records'); final existing = box.values.where((r) => isSameDay(r.date, record.date)).toList(); for (var r in existing) await r.delete(); await box.add(record); } // 根据日期查询健身数据 FitnessRecord? getFitnessData(DateTime date) { final box = Hive.box<FitnessRecord>('fitness_records'); return box.values.firstWhere( (r) => isSameDay(r.date, date), orElse: () => null, ); }
三、关联UI与数据
补全日历页面的查询和展示逻辑:
void _loadFitnessData(DateTime day) { setState(() { _currentRecord = getFitnessData(day); }); } Widget _buildFitnessDataDisplay() { if (_currentRecord == null) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('今日暂无健身记录'), ElevatedButton(onPressed: _showAddRecordDialog, child: Text('添加记录')), ], ), ); } return ListView( padding: EdgeInsets.all(16), children: [ Text('消耗卡路里: ${_currentRecord!.caloriesBurned} kcal', style: TextStyle(fontSize: 18)), SizedBox(height: 16), Text('运动项目:', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), ..._currentRecord!.exercises.map((ex) => ListTile(title: Text(ex))), ElevatedButton(onPressed: _showAddRecordDialog, child: Text('修改记录')), ], ); } void _showAddRecordDialog() { // 实现添加/修改记录的对话框逻辑,调用saveFitnessData保存数据 }
四、细节优化
- 用
isSameDay函数(来自table_calendar)匹配日期,忽略时间部分,确保只按年月日查询。 - 在日历上标记有记录的日期:给
TableCalendar添加eventLoader回调,返回对应日期的事件标记。 - 如需周/月统计,扩展Hive查询逻辑,筛选对应时间段的记录进行计算。
内容的提问来源于stack exchange,提问作者Kaustav Kakoty 7026
相关产品推荐
相关产品推荐

