diff --git a/lib/main.dart b/lib/main.dart index e808c1e..e171f31 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -66,7 +66,7 @@ class _MainPage extends State { appBar: AppBar( centerTitle: true, title: Text('Food Hub'), - backgroundColor: Colors.white, + backgroundColor: Colors.green, leading: IconButton( icon: Icon(Icons.menu), onPressed: () { @@ -96,6 +96,7 @@ class _MainPage extends State { currentIndex: _currentIndex, iconSize: 25, type: BottomNavigationBarType.fixed, + backgroundColor: Colors.white, items: const [ BottomNavigationBarItem(icon: Icon(Icons.home), label: "记录"), BottomNavigationBarItem( diff --git a/lib/record.dart b/lib/record.dart index 2731c41..07cf0de 100644 --- a/lib/record.dart +++ b/lib/record.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:food_hub_app/widgets/recipe/recipe_calendar.dart'; import 'package:food_hub_app/widgets/recipe/recipe_list.dart'; -import 'package:food_hub_app/widgets/recipe/recipe_segment.dart'; import 'package:food_hub_app/widgets/recipe/recipe_timeline.dart'; +import 'package:tdesign_flutter/tdesign_flutter.dart'; import 'models/recipe.dart'; @@ -13,48 +13,64 @@ class RecordPage extends StatefulWidget { State createState() => _RecordPageState(); } -class _RecordPageState extends State { - ViewType _selectedViewType = ViewType.recipe; - +class _RecordPageState extends State + with SingleTickerProviderStateMixin { final List recipeList = [ Recipe("韭菜炒鸡蛋", "家常菜", "2025-05-04", "https://picsum.photos/200", 10, 2, 4), Recipe("红烧肉", "家常菜", "2025-05-05", "https://picsum.photos/200", 12, 4, 7), ]; + late final TabController _tabController = TabController( + length: 3, + vsync: this, + ); + + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + _tabController.dispose(); + super.dispose(); + } + + // 定义标签列表 + final List tabs = [ + const TDTab(text: '菜谱', icon: Icon(Icons.book)), + const TDTab(text: '日历', icon: Icon(Icons.calendar_today)), + const TDTab(text: '时间轴', icon: Icon(Icons.timeline)), + ]; + @override Widget build(BuildContext context) { return Padding( - padding: EdgeInsets.all(10), + padding: EdgeInsets.all(0), child: Column( - mainAxisAlignment: MainAxisAlignment.start, - // crossAxisAlignment: CrossAxisAlignment.start, children: [ - RecipeSegment( - selectedViewType: _selectedViewType, - onViewTypeChanged: (value) { - setState(() { - _selectedViewType = value; - }); - }, + // 标签栏 + TDTabBar( + tabs: tabs, + controller: _tabController, + backgroundColor: Colors.white, + showIndicator: true, + ), + Expanded( + child: Padding( + padding: EdgeInsets.all(5), + child: TabBarView( + controller: _tabController, + children: [ + RecipeList(recipeList: recipeList), + RecipeCalendar(), + RecipeTimeline(recipeList: recipeList), + ], + ), + ), ), - const SizedBox(height: 10), - const Divider(height: 1), - const SizedBox(height: 10), - // 内容区域 - Expanded(child: _buildContent()), ], ), ); } - - Widget _buildContent() { - switch (_selectedViewType) { - case ViewType.recipe: - return RecipeList(recipeList: recipeList); - case ViewType.calendar: - return RecipeCalendar(); - case ViewType.timeline: - return RecipeTimeline(recipeList: recipeList); - } - } } diff --git a/lib/views/login.dart b/lib/views/login.dart index e4ef337..204371c 100644 --- a/lib/views/login.dart +++ b/lib/views/login.dart @@ -13,6 +13,7 @@ class LoginPage extends StatefulWidget { class _LoginPage extends State { final GlobalKey _formKey = GlobalKey(); + late String _username, _password; bool _isObscure = true; Color _eyeColor = Colors.grey; @@ -52,9 +53,6 @@ class _LoginPage extends State { buildUsernameTextField(), const SizedBox(height: 20), buildPasswordTextField(context), - // 紧凑排列:记住密码在上,忘记密码在下,间距缩小 - const SizedBox(height: 8), // 缩小密码框与记住密码的间距 - Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, @@ -102,10 +100,13 @@ class _LoginPage extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ formLabelText(labelText: "账号:"), - const SizedBox(height: 5), + const SizedBox(height: 10), FormBuilderTextField( name: 'username', - decoration: formInputDecoration(hintText: "请输入账号", prefixIcon: Icons.person), + decoration: formInputDecoration( + hintText: "请输入账号", + prefixIcon: Icons.person, + ), validator: FormBuilderValidators.required(), onSaved: (v) => _username = v!, ), @@ -118,7 +119,7 @@ class _LoginPage extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ formLabelText(labelText: "密码:"), - const SizedBox(height: 5), + const SizedBox(height: 10), FormBuilderTextField( name: 'password', obscureText: _isObscure, @@ -139,14 +140,14 @@ class _LoginPage extends State { setState(() { _isObscure = !_isObscure; _eyeColor = - (_isObscure - ? Colors.grey - : Theme.of(context).iconTheme.color)!; + (_isObscure + ? Colors.grey + : Theme.of(context).iconTheme.color)!; }); }, ), ), - ) + ), ], ); } @@ -185,23 +186,20 @@ class _LoginPage extends State { child: SizedBox( height: 45, width: double.infinity, - child: TDButton( + child: TDButton( text: '登录', size: TDButtonSize.large, type: TDButtonType.fill, shape: TDButtonShape.rectangle, theme: TDButtonTheme.primary, - onTap: () => loginClick(context) - ) + onTap: () => loginClick(context), + ), ), ); } Widget buildOtherLoginText() { - return TDDivider( - text: '其他方式登录', - alignment: TextAlignment.center, - ); + return TDDivider(text: '其他方式登录', alignment: TextAlignment.center); } Widget buildOtherMethod(context) { diff --git a/lib/widgets/recipe/recipe_calendar.dart b/lib/widgets/recipe/recipe_calendar.dart index 2051e79..788dfa6 100644 --- a/lib/widgets/recipe/recipe_calendar.dart +++ b/lib/widgets/recipe/recipe_calendar.dart @@ -1,9 +1,19 @@ import 'package:flutter/material.dart'; import 'package:table_calendar/table_calendar.dart'; -class RecipeCalendar extends StatelessWidget { +class RecipeCalendar extends StatefulWidget { const RecipeCalendar({super.key}); + @override + State createState() => _RecipeCalendarState(); +} + +class _RecipeCalendarState extends State { + // 当前选中的日期 + DateTime _selectedDay = DateTime.now(); + // 当前显示的月份 + DateTime _focusedDay = DateTime.now(); + @override Widget build(BuildContext context) { return Column( @@ -12,11 +22,36 @@ class RecipeCalendar extends StatelessWidget { elevation: 0, color: Colors.white, child: TableCalendar( - firstDay: DateTime.utc(2010, 10, 16), - lastDay: DateTime.utc(2030, 3, 14), - focusedDay: DateTime.now(), + locale: 'zh_CN', + headerStyle: const HeaderStyle( + formatButtonVisible: false, + titleCentered: true, + ), + firstDay: DateTime.utc(2010, 1, 1), + lastDay: DateTime.utc(2100, 12, 31), + focusedDay: _focusedDay, + selectedDayPredicate: (day) => isSameDay(_selectedDay, day), + onDaySelected: (selectedDay, focusedDay) { + if (!isSameDay(_selectedDay, selectedDay)) { + setState(() { + _selectedDay = selectedDay; + _focusedDay = focusedDay; + }); + } + }, + onPageChanged: (focusedDay) { + print("cxx"); + _focusedDay = focusedDay; + }, ), ), + + // 显示选中的日期 + const SizedBox(height: 16), + Text( + '选中的日期: ${_selectedDay.year}-${_selectedDay.month}-${_selectedDay.day}', + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), + ), ], ); } diff --git a/lib/widgets/recipe/recipe_segment.dart b/lib/widgets/recipe/recipe_segment.dart deleted file mode 100644 index a609e20..0000000 --- a/lib/widgets/recipe/recipe_segment.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:custom_sliding_segmented_control/custom_sliding_segmented_control.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:food_hub_app/models/recipe.dart'; - -class RecipeSegment extends StatelessWidget { - final ViewType selectedViewType; - final Function(ViewType) onViewTypeChanged; - - const RecipeSegment({super.key, required this.selectedViewType, required this.onViewTypeChanged}); - - @override - Widget build(BuildContext context) { - return CustomSlidingSegmentedControl( - initialValue: 1, - children: { - 1: SizedBox( - width: 50, - child: Text('菜谱', textAlign: TextAlign.center), - ), - 2: SizedBox( - width: 50, - child: Text('日历', textAlign: TextAlign.center), - ), - 3: SizedBox( - width: 50, - child: Text('时间轴', textAlign: TextAlign.center), - ), - }, - decoration: BoxDecoration( - color: CupertinoColors.lightBackgroundGray, - borderRadius: BorderRadius.circular(10), - ), - thumbDecoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(10), - ), - duration: Duration(milliseconds: 300), - curve: Curves.easeInToLinear, - onValueChanged: (value) { - onViewTypeChanged(ViewType.values[value - 1]); - }, - ); - } -} \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index 6011981..f1d5675 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -57,14 +57,6 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "1.0.8" - custom_sliding_segmented_control: - dependency: "direct main" - description: - name: custom_sliding_segmented_control - sha256: bc747b1500284bff36fc8c61774c9a3ca35c1dca4d570141c8a2569b4f984bf3 - url: "https://pub.flutter-io.cn" - source: hosted - version: "1.8.5" easy_refresh: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 1fa3d3a..4762091 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1 +1 @@ -name: food_hub_app description: "A new Flutter project." # The following line prevents the package from being accidentally published to # pub.dev using `flutter pub publish`. This is preferred for private packages. publish_to: 'none' # Remove this line if you wish to publish to pub.dev # The following defines the version and build number for your application. # A version number is three numbers separated by dots, like 1.2.43 # followed by an optional build number separated by a +. # Both the version and the builder number may be overridden in flutter # build by specifying --build-name and --build-number, respectively. # In Android, build-name is used as versionName while build-number used as versionCode. # Read more about Android versioning at https://developer.android.com/studio/publish/versioning # In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. version: 1.0.0+1 environment: sdk: ^3.7.0 # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions # consider running `flutter pub upgrade --major-versions`. Alternatively, # dependencies can be manually updated by changing the version numbers below to # the latest version available on pub.dev. To see which dependencies have newer # versions available, run `flutter pub outdated`. dependencies: flutter: sdk: flutter flutter_localizations: sdk: flutter # The following adds the Cupertino Icons fonts to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.8 timelines_plus: ^1.0.7 table_calendar: ^3.1.3 custom_sliding_segmented_control: ^1.8.5 flutter_datetime_picker_plus: ^2.2.0 flutter_date_pickers: ^0.4.3 flutter_form_builder: ^10.0.0 form_builder_validators: ^11.1.2 # fluttertoast: ^8.2.2 intl: ^0.19.0 tdesign_flutter: ^0.2.3 dependency_overrides: tdesign_flutter_adaptation: 3.16.0 image_picker: 1.0.8 dev_dependencies: flutter_test: sdk: flutter # The "flutter_lints" package below contains a set of recommended lints to # encourage good coding practices. The lint set provided by the package is # activated in the `analysis_options.yaml` file located at the root of your # package. See that file for information about deactivating specific lint # rules and activating additional ones. flutter_lints: ^5.0.0 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec # The following section is specific to Flutter packages. flutter: # The following line ensures that the Material Icons fonts is # included with your application, so that you can use the icons in # the material Icons class. uses-material-design: true # To add assets to your application, add an assets section, like this: # assets: # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/to/resolution-aware-images # For details regarding adding assets from package dependencies, see # https://flutter.dev/to/asset-from-package # To add custom fonts to your application, add a fonts section here, # in this "flutter" section. Each entry in this list should have a # "family" key with the fonts family name, and a "fonts" key with a # list giving the asset and other descriptors for the fonts. For # example: # fonts: # - family: Schyler # fonts: # - asset: fonts/Schyler-Regular.ttf # - asset: fonts/Schyler-Italic.ttf # style: italic # - family: Trajan Pro # fonts: # - asset: fonts/TrajanPro.ttf # - asset: fonts/TrajanPro_Bold.ttf # weight: 700 # # For details regarding fonts from package dependencies, # see https://flutter.dev/to/font-from-package fonts: - family: CustomFont fonts: - asset: fonts/custom.ttf \ No newline at end of file +name: food_hub_app description: "A new Flutter project." # The following line prevents the package from being accidentally published to # pub.dev using `flutter pub publish`. This is preferred for private packages. publish_to: 'none' # Remove this line if you wish to publish to pub.dev # The following defines the version and build number for your application. # A version number is three numbers separated by dots, like 1.2.43 # followed by an optional build number separated by a +. # Both the version and the builder number may be overridden in flutter # build by specifying --build-name and --build-number, respectively. # In Android, build-name is used as versionName while build-number used as versionCode. # Read more about Android versioning at https://developer.android.com/studio/publish/versioning # In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. version: 1.0.0+1 environment: sdk: ^3.7.0 # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions # consider running `flutter pub upgrade --major-versions`. Alternatively, # dependencies can be manually updated by changing the version numbers below to # the latest version available on pub.dev. To see which dependencies have newer # versions available, run `flutter pub outdated`. dependencies: flutter: sdk: flutter flutter_localizations: sdk: flutter # The following adds the Cupertino Icons fonts to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.8 timelines_plus: ^1.0.7 table_calendar: ^3.1.3 flutter_datetime_picker_plus: ^2.2.0 flutter_date_pickers: ^0.4.3 flutter_form_builder: ^10.0.0 form_builder_validators: ^11.1.2 # fluttertoast: ^8.2.2 intl: ^0.19.0 tdesign_flutter: ^0.2.3 dependency_overrides: tdesign_flutter_adaptation: 3.16.0 image_picker: 1.0.8 dev_dependencies: flutter_test: sdk: flutter # The "flutter_lints" package below contains a set of recommended lints to # encourage good coding practices. The lint set provided by the package is # activated in the `analysis_options.yaml` file located at the root of your # package. See that file for information about deactivating specific lint # rules and activating additional ones. flutter_lints: ^5.0.0 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec # The following section is specific to Flutter packages. flutter: # The following line ensures that the Material Icons fonts is # included with your application, so that you can use the icons in # the material Icons class. uses-material-design: true # To add assets to your application, add an assets section, like this: # assets: # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/to/resolution-aware-images # For details regarding adding assets from package dependencies, see # https://flutter.dev/to/asset-from-package # To add custom fonts to your application, add a fonts section here, # in this "flutter" section. Each entry in this list should have a # "family" key with the fonts family name, and a "fonts" key with a # list giving the asset and other descriptors for the fonts. For # example: # fonts: # - family: Schyler # fonts: # - asset: fonts/Schyler-Regular.ttf # - asset: fonts/Schyler-Italic.ttf # style: italic # - family: Trajan Pro # fonts: # - asset: fonts/TrajanPro.ttf # - asset: fonts/TrajanPro_Bold.ttf # weight: 700 # # For details regarding fonts from package dependencies, # see https://flutter.dev/to/font-from-package fonts: - family: CustomFont fonts: - asset: fonts/custom.ttf \ No newline at end of file