diff --git a/lib/main.dart b/lib/main.dart index a857e78..9b7ecdc 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -2,10 +2,11 @@ import 'package:fitnote/models/health.dart'; import 'package:fitnote/pages/home_page.dart'; import 'package:fitnote/provider/health_provider.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:provider/provider.dart'; -void main() async{ +void main() async { // 初始化Hive await Hive.initFlutter(); @@ -13,12 +14,12 @@ void main() async{ Hive.registerAdapter(HealthRecordAdapter()); final healthsBox = await Hive.openBox('healths'); + healthsBox.clear(); + // await Hive.deleteBoxFromDisk('healths'); runApp( MultiProvider( - providers: [ - ChangeNotifierProvider(create: (_) => HealthProvider()) - ], + providers: [ChangeNotifierProvider(create: (_) => HealthProvider())], child: MyApp(), ), ); @@ -31,6 +32,21 @@ class MyApp extends StatelessWidget { Widget build(BuildContext context) { return MaterialApp( title: '健康记录', + localizationsDelegates: [ + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate + ], + supportedLocales: [const Locale('zh'), const Locale('zh', 'CN')], + locale: Locale('zh', 'CN'), + builder: (context, child) { + return MediaQuery( + data: MediaQuery.of(context).copyWith( + alwaysUse24HourFormat: true, + ), + child: child!, + ); + }, theme: ThemeData( fontFamily: 'Inter', scaffoldBackgroundColor: const Color(0xFFF9FAFB), diff --git a/lib/models/health.dart b/lib/models/health.dart index 32541e1..ea30254 100644 --- a/lib/models/health.dart +++ b/lib/models/health.dart @@ -25,9 +25,6 @@ class HealthRecord extends HiveObject { @HiveField(5) String sleepEndTime; - @HiveField(6) - num sleepDuration; - @HiveField(7) String date; @@ -38,11 +35,10 @@ class HealthRecord extends HiveObject { required this.weight, required this.sleepStartTime, required this.sleepEndTime, - required this.sleepDuration, required this.date, }); - static HealthRecord getEmpty() { + static HealthRecord getEmpty(String date) { return HealthRecord( id: DateTime.now().millisecondsSinceEpoch ~/ 1000, sportProject: '', @@ -50,21 +46,27 @@ class HealthRecord extends HiveObject { weight: 0, sleepStartTime: '', sleepEndTime: '', - sleepDuration: 0, - date: '', + date: date, ); } - static HealthRecord getDefault() { + HealthRecord copyWith({ + int? id, + num? weight, + String? sportProject, + num? sportDuration, + String? sleepStartTime, + String? sleepEndTime, + String? date, + }) { return HealthRecord( - id: DateTime.now().millisecondsSinceEpoch ~/ 1000, - sportProject: '跑步', - sportDuration: 30, - weight: 70, - sleepStartTime: '', - sleepEndTime: '', - sleepDuration: 0, - date: '', + id: id ?? this.id, + date: date ?? this.date, + weight: weight ?? this.weight, + sportProject: sportProject ?? this.sportProject, + sportDuration: sportDuration ?? this.sportDuration, + sleepStartTime: sleepStartTime ?? this.sleepStartTime, + sleepEndTime: sleepEndTime ?? this.sleepEndTime ); } } diff --git a/lib/models/health.g.dart b/lib/models/health.g.dart index e904ad6..6eaf411 100644 --- a/lib/models/health.g.dart +++ b/lib/models/health.g.dart @@ -23,7 +23,6 @@ class HealthRecordAdapter extends TypeAdapter { weight: fields[3] as num, sleepStartTime: fields[4] as String, sleepEndTime: fields[5] as String, - sleepDuration: fields[6] as num, date: fields[7] as String, ); } @@ -31,7 +30,7 @@ class HealthRecordAdapter extends TypeAdapter { @override void write(BinaryWriter writer, HealthRecord obj) { writer - ..writeByte(8) + ..writeByte(7) ..writeByte(0) ..write(obj.id) ..writeByte(1) @@ -44,8 +43,6 @@ class HealthRecordAdapter extends TypeAdapter { ..write(obj.sleepStartTime) ..writeByte(5) ..write(obj.sleepEndTime) - ..writeByte(6) - ..write(obj.sleepDuration) ..writeByte(7) ..write(obj.date); } diff --git a/lib/provider/health_provider.dart b/lib/provider/health_provider.dart index 8119138..2b85297 100644 --- a/lib/provider/health_provider.dart +++ b/lib/provider/health_provider.dart @@ -1,43 +1,40 @@ import 'package:fitnote/models/health.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_common/flutter_common.dart'; class HealthProvider with ChangeNotifier { - late HealthRecord _formItem; - - HealthRecord get formItem => _formItem; - - void resetForm() { - _formItem = HealthRecord.getEmpty(); - notifyListeners(); - } + late HealthRecord formItem; + String date = formatDate(DateTime.now()); + RecordType type = RecordType.weight; + bool isEditing = false; void initForm(HealthRecord record) { - _formItem = record; + formItem = record; notifyListeners(); } void updateWeight(num weight) { - _formItem.weight = weight; + formItem.weight = weight; notifyListeners(); } void updateSportProject(String sportProject) { - _formItem.sportProject = sportProject; + formItem.sportProject = sportProject; notifyListeners(); } void updateSportDuration(num sportDuration) { - _formItem.sportDuration = sportDuration; + formItem.sportDuration = sportDuration; notifyListeners(); } void updateSleepStartTime(String sleepStartTime) { - _formItem.sleepStartTime = sleepStartTime; + formItem.sleepStartTime = sleepStartTime; notifyListeners(); } void updateSleepEndTime(String sleepEndTime) { - _formItem.sleepEndTime = sleepEndTime; + formItem.sleepEndTime = sleepEndTime; notifyListeners(); } } diff --git a/lib/service/health_service.dart b/lib/service/health_service.dart index 9504dbd..e2759fe 100644 --- a/lib/service/health_service.dart +++ b/lib/service/health_service.dart @@ -20,15 +20,25 @@ class HealthService { } HealthRecord getAllRecordByDate(String date) { - return box.values.toList().firstWhere( + final record = box.values.toList().firstWhere( (item) => item.date == date, - orElse: () => HealthRecord.getEmpty(), + orElse: () => HealthRecord.getEmpty(date), ); + + return record.copyWith(); } Future updateRecord(HealthRecord record) async { try { - await record.save(); + List records = + box.values.where((item) => item.date == record.date).toList(); + + if (records.isEmpty) { + await addRecord(record); + } else { + await record.save(); + } + return true; } catch (e) { return false; diff --git a/lib/utils/record_utils.dart b/lib/utils/record_utils.dart new file mode 100644 index 0000000..0c9cd8e --- /dev/null +++ b/lib/utils/record_utils.dart @@ -0,0 +1,55 @@ +import 'package:fitnote/models/health.dart'; +import 'package:flutter/material.dart'; + +bool checkHasRecordValue(HealthRecord record, RecordType type) { + switch (type) { + case RecordType.weight: + return record.weight != 0; + case RecordType.sport: + return record.sportProject != ''; + case RecordType.sleep: + return record.sleepStartTime != ''; + } +} + +// 将字符串时间转换为 TimeOfDay +TimeOfDay parseTime(String timeString) { + if (timeString.isEmpty) { + return TimeOfDay.now(); + } + try { + final parts = timeString.split(':'); + return TimeOfDay(hour: int.parse(parts[0]), minute: int.parse(parts[1])); + } catch (e) { + return TimeOfDay.now(); + } +} + +// 将 TimeOfDay 格式化为字符串 (HH:mm) +String formatTime(TimeOfDay time) { + return '${time.hour.toString().padLeft(2, '0')}:${time.minute.toString().padLeft(2, '0')}'; +} + +// 计算睡眠时长 +String calculateDuration(String startTime, String endTime) { + try { + final start = parseTime(startTime); + final end = parseTime(endTime); + + int startMinutes = start.hour * 60 + start.minute; + int endMinutes = end.hour * 60 + end.minute; + + // 处理跨天情况(如果结束时间小于开始时间,认为是第二天) + if (endMinutes < startMinutes) { + endMinutes += 24 * 60; // 加上一天的分钟数 + } + + int durationMinutes = endMinutes - startMinutes; + int hours = durationMinutes ~/ 60; + int minutes = durationMinutes % 60; + + return '${hours}小时${minutes}分钟'; + } catch (e) { + return '计算错误'; + } +} diff --git a/lib/widget/dropdown_select.dart b/lib/widget/dropdown_select.dart index ccd8cc9..0cff85c 100644 --- a/lib/widget/dropdown_select.dart +++ b/lib/widget/dropdown_select.dart @@ -1,3 +1,4 @@ +import 'package:fitnote/widget/record/common.dart'; import 'package:flutter/material.dart'; import 'package:getwidget/getwidget.dart'; @@ -15,17 +16,15 @@ class DropdownSelect extends StatelessWidget { @override Widget build(BuildContext context) { - final colors = Theme.of(context).colorScheme; + final double width = 150; + final double height = 36; return Container( - width: 150, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(6), - border: Border.all(color: colors.primary, width: 1.5), - ), + width: width, + decoration: buildBoxDecoration(context), child: DropdownButtonHideUnderline( child: GFDropdown( - itemHeight: 32, + itemHeight: height, padding: const EdgeInsets.all(0), borderRadius: BorderRadius.circular(8), value: value, diff --git a/lib/widget/number_input.dart b/lib/widget/number_input.dart index 88da71b..aceb3af 100644 --- a/lib/widget/number_input.dart +++ b/lib/widget/number_input.dart @@ -1,3 +1,4 @@ +import 'package:fitnote/widget/record/common.dart'; import 'package:flutter/material.dart'; class NumberInput extends StatefulWidget { @@ -29,6 +30,8 @@ class _NumberInputState extends State { late num _currentValue; final Color disabledColor = Colors.grey.shade400; + final double width = 150; + final double height = 36; @override void initState() { @@ -74,8 +77,8 @@ class _NumberInputState extends State { final colors = Theme.of(context).colorScheme; return Container( - width: 32, - height: 32, + width: height, + height: height, child: Material( color: disabled ? disabledColor : colors.primary.withAlpha(100), child: InkWell( @@ -89,14 +92,9 @@ class _NumberInputState extends State { @override Widget build(BuildContext context) { - final colors = Theme.of(context).colorScheme; - return Container( - width: 150, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(6), - border: Border.all(color: colors.primary, width: 1.5), - ), + width: width, + decoration: buildBoxDecoration(context), child: IntrinsicWidth( child: Row( mainAxisSize: MainAxisSize.min, diff --git a/lib/widget/record/common.dart b/lib/widget/record/common.dart index 4e8bbe2..b24a93d 100644 --- a/lib/widget/record/common.dart +++ b/lib/widget/record/common.dart @@ -35,3 +35,13 @@ Widget buildCircleIcon({ child: Icon(icon, color: Theme.of(context).colorScheme.primary, size: 18), ); } + +BoxDecoration buildBoxDecoration(BuildContext context) { + return BoxDecoration( + borderRadius: BorderRadius.circular(8), + border: Border.all( + color: Theme.of(context).colorScheme.primary, + width: 1.5, + ), + ); +} diff --git a/lib/widget/record/record_daily.dart b/lib/widget/record/record_daily.dart index 995ed22..b5a19bf 100644 --- a/lib/widget/record/record_daily.dart +++ b/lib/widget/record/record_daily.dart @@ -1,11 +1,13 @@ import 'package:fitnote/models/health.dart'; import 'package:fitnote/provider/health_provider.dart'; import 'package:fitnote/service/health_service.dart'; +import 'package:fitnote/utils/record_utils.dart'; import 'package:fitnote/widget/record/common.dart'; import 'package:fitnote/widget/record/record_form.dart'; import 'package:flutter/material.dart'; import 'package:flutter_common/widget/common_widget.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:getwidget/getwidget.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; @@ -19,24 +21,18 @@ class RecordDaily extends StatefulWidget { class _RecordDailyState extends State { final HealthService service = HealthService(); - late HealthRecord _record; + HealthRecord _record = HealthRecord.getEmpty(''); @override void initState() { super.initState(); - _record = service.getAllRecordByDate('2025-12-01'); - } - final recordForm = HealthRecord( - id: 1, - sportProject: '羽毛球', - sportDuration: 20, - sleepStartTime: '23:00', - sleepEndTime: '24:00', - sleepDuration: 60, - weight: 70, - date: '2025-11-28', - ); + WidgetsBinding.instance.addPostFrameCallback((_) { + final provider = context.read(); + _record = service.getAllRecordByDate(provider.date); + provider.initForm(HealthRecord.getEmpty(provider.date)); + }); + } @override Widget build(BuildContext context) { @@ -142,7 +138,7 @@ class _RecordDailyState extends State { borderRadius: BorderRadius.circular(20), ), child: Icon( - _checkHasRecordValue(type) + checkHasRecordValue(_record, type) ? FontAwesomeIcons.pencil : FontAwesomeIcons.plus, color: type.color, @@ -159,29 +155,112 @@ class _RecordDailyState extends State { ); } - bool _checkHasRecordValue(RecordType type) { - switch (type) { - case RecordType.weight: - return _record.weight != 0; - case RecordType.sport: - return _record.sportProject != ''; - case RecordType.sleep: - return _record.sleepStartTime != ''; - } - } - void onTapRecord(RecordType type) { final provider = context.read(); - provider.initForm(HealthRecord.getDefault()); + provider.isEditing = checkHasRecordValue(_record, type); + provider.type = type; + + if (provider.isEditing) { + _initRecord(provider); + } else { + _defaultRecord(provider); + } showDialog( context: context, - builder: (context) => Dialog(child: RecordForm(type: type)), + builder: + (context) => Dialog( + child: Padding( + padding: EdgeInsets.all(20), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [RecordForm(type: type), _buildDialogButton()], + ), + ), + ), ); } + Widget _buildDialogButton() { + final colors = Theme.of(context).colorScheme; + + return Row( + children: [ + Expanded( + child: GFButton( + onPressed: () { + Navigator.of(context).pop(); + _resetRecord(); + }, + color: colors.secondary, + text: "取消", + ), + ), + const SizedBox(width: 12), + Expanded( + child: GFButton( + onPressed: () { + Navigator.of(context).pop(); + _saveRecord(); + }, + color: colors.primary, + text: "确定", + ), + ), + ], + ); + } + + void _initRecord(HealthProvider provider) { + switch (provider.type) { + case RecordType.weight: + provider.updateWeight(_record.weight); + break; + case RecordType.sport: + provider.updateSportProject(_record.sportProject); + provider.updateSportDuration(_record.sportDuration); + break; + case RecordType.sleep: + provider.updateSleepStartTime(_record.sleepStartTime); + provider.updateSleepEndTime(_record.sleepEndTime); + break; + } + } + + void _resetRecord() { + final provider = context.read(); + if (!provider.isEditing) { + _defaultRecord(provider); + } + } + + void _defaultRecord(HealthProvider provider) { + switch (provider.type) { + case RecordType.weight: + provider.updateWeight(70); + break; + case RecordType.sport: + provider.updateSportProject('跑步'); + provider.updateSportDuration(30); + break; + case RecordType.sleep: + provider.updateSleepStartTime(''); + provider.updateSleepEndTime(''); + break; + } + } + + void _saveRecord() async { + final provider = context.read(); + await service.updateRecord(provider.formItem); + + setState(() { + _record = service.getAllRecordByDate(provider.date); + }); + } + Widget _buildRecordContent(RecordType type) { - if (!_checkHasRecordValue(type)) { + if (!checkHasRecordValue(_record, type)) { return Text( "尚未记录今日数据,点击添加", style: TextStyle(fontSize: 12, color: Colors.grey[500]), @@ -195,8 +274,16 @@ class _RecordDailyState extends State { case RecordType.sport: title = "${_record.sportProject} · ${_record.sportDuration}分钟"; case RecordType.sleep: - title = - "入睡 ${_record.sleepStartTime} · 起床 ${_record.sleepEndTime} · ${_record.sleepDuration}分钟"; + final startTime = _record.sleepStartTime; + final endTime = _record.sleepEndTime; + if (startTime.isNotEmpty && endTime.isNotEmpty) { + final duration = calculateDuration(startTime, endTime); + title = "入睡 $startTime · 起床 $endTime · ${duration}"; + } else if (startTime.isNotEmpty) { + title = "入睡 $startTime"; + } else if (endTime.isNotEmpty) { + title = "起床 $endTime"; + } } return Text( diff --git a/lib/widget/record/record_form.dart b/lib/widget/record/record_form.dart index b95f31d..1488e0a 100644 --- a/lib/widget/record/record_form.dart +++ b/lib/widget/record/record_form.dart @@ -1,10 +1,11 @@ import 'package:fitnote/models/health.dart'; import 'package:fitnote/provider/health_provider.dart'; import 'package:fitnote/service/health_service.dart'; +import 'package:fitnote/utils/record_utils.dart'; import 'package:fitnote/widget/dropdown_select.dart'; import 'package:fitnote/widget/number_input.dart'; +import 'package:fitnote/widget/time_picker.dart'; import 'package:flutter/material.dart'; -import 'package:getwidget/getwidget.dart'; import 'package:provider/provider.dart'; class RecordForm extends StatefulWidget { @@ -21,40 +22,7 @@ class _RecordFormState extends State { @override Widget build(BuildContext context) { - return Padding(padding: EdgeInsets.all(20), child: _buildFormContent()); - } - - Widget _buildFormButton() { - final colors = Theme.of(context).colorScheme; - - return Row( - children: [ - Expanded( - child: GFButton( - onPressed: () => Navigator.of(context).pop(), - color: colors.secondary, - text: "取消", - ), - ), - const SizedBox(width: 12), - Expanded( - child: GFButton( - onPressed: () { - _saveRecord(); - Navigator.of(context).pop(); - }, - color: colors.primary, - text: "确定", - ), - ), - ], - ); - } - - void _saveRecord() { - final provider = context.read(); - - // service.updateRecord(provider.formItem); + return _buildFormContent(); } Widget _buildFormTitle(String title) { @@ -72,6 +40,34 @@ class _RecordFormState extends State { return Text(title, style: TextStyle(fontSize: 16)); } + Widget _buildSleepDuration(HealthRecord record) { + final startTime = record.sleepStartTime; + final endTime = record.sleepEndTime; + late String duration = calculateDuration(startTime, endTime); + + if (startTime.isNotEmpty && endTime.isNotEmpty) { + duration = calculateDuration(startTime, endTime); + } else { + duration = ""; + } + + return Container( + padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8), + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.surface, + borderRadius: BorderRadius.circular(8), + ), + child: Text( + '睡眠时长:$duration', + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Theme.of(context).colorScheme.primary, + ), + ), + ); + } + Widget _buildFormContent() { final provider = context.watch(); @@ -98,7 +94,6 @@ class _RecordFormState extends State { ], ), SizedBox(height: 20), - _buildFormButton(), ], ); case RecordType.sport: @@ -120,7 +115,6 @@ class _RecordFormState extends State { ], ), SizedBox(height: 20), - Row( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -137,18 +131,52 @@ class _RecordFormState extends State { ], ), SizedBox(height: 24), - _buildFormButton(), ], ); case RecordType.sleep: return Column( mainAxisSize: MainAxisSize.min, children: [ - _buildFiledTitle('记录睡眠'), + _buildFormTitle('记录睡眠'), + SizedBox(height: 24), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + _buildFiledTitle('入睡时间:'), + SizedBox(width: 10), + TimePicker( + initialTime: parseTime(provider.formItem.sleepStartTime), + label: provider.formItem.sleepStartTime, + onTimeSelected: (time) { + provider.updateSleepStartTime(formatTime(time)); + final startTime = provider.formItem.sleepStartTime; + final endTime = provider.formItem.sleepEndTime; + calculateDuration(startTime, endTime); + }, + ), + ], + ), SizedBox(height: 20), - // 这里添加睡眠相关的输入控件 + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + _buildFiledTitle('起床时间:'), + SizedBox(width: 10), + TimePicker( + initialTime: parseTime(provider.formItem.sleepEndTime), + label: provider.formItem.sleepEndTime, + onTimeSelected: (time) { + provider.updateSleepEndTime(formatTime(time)); + final startTime = provider.formItem.sleepStartTime; + final endTime = provider.formItem.sleepEndTime; + calculateDuration(startTime, endTime); + }, + ), + ], + ), SizedBox(height: 20), - _buildFormButton(), + _buildSleepDuration(provider.formItem), + SizedBox(height: 24), ], ); } diff --git a/lib/widget/time_picker.dart b/lib/widget/time_picker.dart new file mode 100644 index 0000000..65fc9cf --- /dev/null +++ b/lib/widget/time_picker.dart @@ -0,0 +1,69 @@ +import 'package:fitnote/widget/record/common.dart'; +import 'package:flutter/material.dart'; + +class TimePicker extends StatelessWidget { + final TimeOfDay initialTime; + final ValueChanged onTimeSelected; + final String? label; + + const TimePicker({ + super.key, + required this.initialTime, + required this.onTimeSelected, + this.label, + }); + + @override + Widget build(BuildContext context) { + final double width = 150; + final double height = 36; + + return Container( + width: width, + height: height, + decoration: buildBoxDecoration(context), + child: InkWell( + onTap: () => _showTimePicker(context), + borderRadius: BorderRadius.circular(8), + child: Container( + padding: const EdgeInsets.all(0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + Icon(Icons.access_time, size: 20, color: Colors.grey[600]), + const SizedBox(width: 12), + Text( + label ?? _formatTime(initialTime), + style: TextStyle( + fontSize: 16, + fontWeight: FontWeight.w500, + color: Colors.grey[800], + ), + ), + const SizedBox(width: 8), + Icon(Icons.arrow_drop_down, size: 20, color: Colors.grey[500]), + ], + ), + ), + ), + ); + } + + Future _showTimePicker(BuildContext context) async { + final TimeOfDay? picked = await showTimePicker( + context: context, + initialTime: initialTime, + initialEntryMode: TimePickerEntryMode.dialOnly, + ); + + if (picked != null) { + onTimeSelected(picked); + } + } + + String _formatTime(TimeOfDay time) { + return '${time.hour.toString().padLeft(2, '0')}:${time.minute.toString().padLeft(2, '0')}'; + } +} diff --git a/pubspec.lock b/pubspec.lock index 698342f..b7c41cc 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -338,6 +338,11 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "5.0.0" + flutter_localizations: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" flutter_plugin_android_lifecycle: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index d0e75fa..3da665b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1 +1 @@ -name: fitnote description: "记录健康生活" publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: sdk: ^3.7.0 dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.8 getwidget: ^7.0.0 intl: ^0.19.0 font_awesome_flutter: ^10.7.0 hive: ^2.2.3 hive_flutter: ^1.1.0 numberpicker: ^2.1.2 provider: ^6.1.1 flutter_common: path: ..\flutter_common dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^5.0.0 hive_generator: ^2.0.1 build_runner: ^2.4.6 # The following section is specific to Flutter packages. flutter: uses-material-design: true \ No newline at end of file +name: fitnote description: "记录健康生活" publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: sdk: ^3.7.0 dependencies: flutter: sdk: flutter flutter_localizations: sdk: flutter cupertino_icons: ^1.0.8 getwidget: ^7.0.0 intl: ^0.19.0 font_awesome_flutter: ^10.7.0 hive: ^2.2.3 hive_flutter: ^1.1.0 numberpicker: ^2.1.2 provider: ^6.1.1 flutter_common: path: ..\flutter_common dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^5.0.0 hive_generator: ^2.0.1 build_runner: ^2.4.6 # The following section is specific to Flutter packages. flutter: uses-material-design: true \ No newline at end of file