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

Flutter健身追踪应用中基于日历的本地日期数据管理咨询

Flutter本地日历式健身数据追踪实现指南

一、选择日历UI组件

直接用table_calendar包,这是Flutter生态里最成熟的日历组件,支持日期选择、自定义样式,完全适配需求。

  1. 添加依赖到pubspec.yaml:
    dependencies:
      table_calendar: ^3.0.0
    
  2. 基础使用示例:
    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更适合存储带日期的结构化健身数据。

  1. 添加依赖:
    dependencies:
      hive: ^2.0.0
      hive_flutter: ^1.1.0
    dev_dependencies:
      hive_generator: ^1.1.0
      build_runner: ^2.0.0
    
  2. 初始化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());
    }
    
  3. 定义健身数据模型:
    创建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
    
  4. 核心数据操作方法:
    // 保存当日健身数据(覆盖同日期旧数据)
    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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 19:02:45