From 4592b5dfbad9a8c15ddd533c5c0e61d568b4c564 Mon Sep 17 00:00:00 2001 From: Zhou Weidong <502333560@qq.com> Date: Thu, 22 Oct 2026 19:29:12 +0800 Subject: [PATCH] =?UTF-8?q?feat(home):=20=E9=A6=96=E9=A1=B5=E5=9B=BE?= =?UTF-8?q?=E6=A0=87=E5=8C=BA=E5=88=86=E5=AE=9E=E5=BF=83=E9=80=89=E4=B8=AD?= =?UTF-8?q?=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/icon/film_reel_filled.png | Bin 0 -> 2624 bytes docs/plans/PROGRESS.md | 6 ++++++ lib/core/widgets/app_bottom_nav.dart | 11 ++++++++--- lib/core/widgets/app_root_tab.dart | 9 +++++++-- test/home/app_bottom_nav_test.dart | 18 ++++++++++++------ test/home/home_nav_ui_test.dart | 12 +++++++++++- 6 files changed, 44 insertions(+), 12 deletions(-) create mode 100644 assets/icon/film_reel_filled.png diff --git a/assets/icon/film_reel_filled.png b/assets/icon/film_reel_filled.png new file mode 100644 index 0000000000000000000000000000000000000000..719167143c6be7bf7fb64d3398fe8c8067d0ae14 GIT binary patch literal 2624 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 o#O^*R!dcT9_#bQ6U!6}l_zf2F Icon( - item.icon, + fallbackIcon, size: AppDimens.navIcon, color: color, ), diff --git a/lib/core/widgets/app_root_tab.dart b/lib/core/widgets/app_root_tab.dart index c0e9d2d..c9f0c96 100644 --- a/lib/core/widgets/app_root_tab.dart +++ b/lib/core/widgets/app_root_tab.dart @@ -7,14 +7,18 @@ import 'app_bottom_nav.dart'; /// 客户端根导航的固定顺序。 enum AppRootTab { - home(assetPath: 'assets/icon/film_reel.png'), + home( + assetPath: 'assets/icon/film_reel.png', + selectedAssetPath: 'assets/icon/film_reel_filled.png', + ), recommend(), following(), mine(); - const AppRootTab({this.assetPath}); + const AppRootTab({this.assetPath, this.selectedAssetPath}); final String? assetPath; + final String? selectedAssetPath; } extension AppRootTabUi on AppRootTab { @@ -72,6 +76,7 @@ class AppRootBottomNav extends StatelessWidget { icon: tab.icon, selectedIcon: tab.selectedIcon, assetPath: tab.assetPath, + selectedAssetPath: tab.selectedAssetPath, label: tab.label(l10n), selected: tab == selected, onTap: () => onSelected(tab), diff --git a/test/home/app_bottom_nav_test.dart b/test/home/app_bottom_nav_test.dart index 37a44be..289d568 100644 --- a/test/home/app_bottom_nav_test.dart +++ b/test/home/app_bottom_nav_test.dart @@ -181,8 +181,8 @@ void main() { }); testWidgets('should_fallback_when_asset_icon_is_missing', (tester) async { - await tester.pumpWidget( - MaterialApp( + Widget navigation({required bool selected}) { + return MaterialApp( home: Scaffold( bottomNavigationBar: AppBottomNav( items: [ @@ -191,17 +191,23 @@ void main() { icon: Icons.theaters_outlined, selectedIcon: Icons.theaters, assetPath: 'assets/icon/missing_film_reel.png', + selectedAssetPath: 'assets/icon/missing_film_reel_filled.png', label: 'Home', - selected: true, + selected: selected, onTap: () {}, ), ], ), ), - ), - ); - await tester.pumpAndSettle(); + ); + } + await tester.pumpWidget(navigation(selected: true)); + await tester.pumpAndSettle(); + expect(find.byIcon(Icons.theaters), findsOneWidget); + + await tester.pumpWidget(navigation(selected: false)); + await tester.pumpAndSettle(); expect(find.byIcon(Icons.theaters_outlined), findsOneWidget); }); } diff --git a/test/home/home_nav_ui_test.dart b/test/home/home_nav_ui_test.dart index 1214bb8..354fc46 100644 --- a/test/home/home_nav_ui_test.dart +++ b/test/home/home_nav_ui_test.dart @@ -235,7 +235,7 @@ void main() { ); expect( (selectedHomeImage.image as AssetImage).assetName, - 'assets/icon/film_reel.png', + 'assets/icon/film_reel_filled.png', ); expect( Size(selectedHomeImage.width!, selectedHomeImage.height!), @@ -300,6 +300,16 @@ void main() { .colorFilter, const ColorFilter.mode(AppColors.navUnselected, BlendMode.srcIn), ); + final unselectedHomeImage = tester.widget( + find.descendant( + of: find.byKey(const Key('tab-home')), + matching: find.byType(Image), + ), + ); + expect( + (unselectedHomeImage.image as AssetImage).assetName, + 'assets/icon/film_reel.png', + ); }); testWidgets('should_map_four_tabs_to_home_recommend_following_and_me', (