From d79e2006501cd1b7a405bc2b93e5d41dcbe14031 Mon Sep 17 00:00:00 2001 From: Zhou Weidong <502333560@qq.com> Date: Thu, 22 Oct 2026 20:49:54 +0800 Subject: [PATCH] =?UTF-8?q?style(recommend):=20=E6=8C=89=E6=88=AA=E5=9B=BE?= =?UTF-8?q?=E9=87=8D=E5=81=9A=E5=85=A8=E9=83=A8=E7=9F=AD=E5=89=A7=E7=AD=9B?= =?UTF-8?q?=E9=80=89=E5=8C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/plans/PROGRESS.md | 2 + lib/core/theme/app_colors.dart | 6 +- lib/core/theme/app_dimens.dart | 16 +++-- .../widgets/all_dramas_filter_grid.dart | 71 ++++++------------- test/recommend/recommend_sections_test.dart | 30 ++++++-- 5 files changed, 62 insertions(+), 63 deletions(-) diff --git a/docs/plans/PROGRESS.md b/docs/plans/PROGRESS.md index 0fd1f8e..68ccc5f 100644 --- a/docs/plans/PROGRESS.md +++ b/docs/plans/PROGRESS.md @@ -1214,3 +1214,5 @@ $ flutter test - 第三行筛选完整展示,卡片继续复用首页组件;`flutter analyze`:No issues found。 - 筛选项字号提升到 15、圆角 15;筛选区移出滚动容器并固定吸顶,下拉刷新仅作用于网格。 - 四行首项文字统一到同一 x;行高 30、行距 6、项目距 12,第 4 行保持弹性空白后固定筛选图标。 +- 按最新截图改为 16sp、32 高、10 行距、16 项距;选中态为 `#21090E` 底配 `#FF4D6A` 粉字。 +- 第 4 行复用选中胶囊样式,右侧改为 44×44 圆形深灰按钮和 22 三横线图标;`flutter analyze` 无问题。 diff --git a/lib/core/theme/app_colors.dart b/lib/core/theme/app_colors.dart index 5dbe249..f1d5aec 100644 --- a/lib/core/theme/app_colors.dart +++ b/lib/core/theme/app_colors.dart @@ -77,7 +77,11 @@ abstract final class AppColors { static const contentSurface = Color(0xFF1C1C1E); static const contentChip = Color(0xFF2C2C2E); static const contentBorder = Color(0x1AFFFFFF); - static const filterChipSelected = Color(0xFF4A1E1E); + static const filterChipSelected = Color(0xFF21090E); + static const filterChipTextSelected = Color(0xFFFF4D6A); + static const filterChipTextInactive = Color(0xFF8A8A8A); + static const filterMenuButton = Color(0xFF2A2A2A); + static const filterMenuIcon = Color(0xFFBDBDBD); /// 「我的」页卡片与描边。 static const mineCard = Color(0xFF16161A); diff --git a/lib/core/theme/app_dimens.dart b/lib/core/theme/app_dimens.dart index cf402ff..0fc48db 100644 --- a/lib/core/theme/app_dimens.dart +++ b/lib/core/theme/app_dimens.dart @@ -137,17 +137,19 @@ abstract final class AppDimens { static const double recommendCardWidth = 122; /// 全部短剧筛选与追剧双列。 - static const double filterChipFont = 15; - static const double filterChipHeight = 30; - static const double filterChipRadius = 15; - static const double filterChipHorizontalPadding = 12; - static const double filterRowGap = 6; - static const double filterItemGap = 12; + static const double filterChipFont = 16; + static const double filterChipHeight = 32; + static const double filterChipRadius = 16; + static const double filterChipHorizontalPadding = 14; + static const double filterRowGap = 10; + static const double filterItemGap = 16; static const double allDramasHorizontal = 12; static const double allDramasGridGap = 6; static const double allDramasGridRowGap = 12; static const double allDramasFilterToGridGap = 12; - static const double allDramasFilterIcon = 26; + static const double allDramasFilterIcon = 22; + static const double allDramasFilterButton = 44; + static const double allDramasFilterRight = 12; static const double followingTabFont = 16; static const double followingGridAspectRatio = 0.5; diff --git a/lib/pages/recommend/widgets/all_dramas_filter_grid.dart b/lib/pages/recommend/widgets/all_dramas_filter_grid.dart index 1aa04d6..ff5d0dc 100644 --- a/lib/pages/recommend/widgets/all_dramas_filter_grid.dart +++ b/lib/pages/recommend/widgets/all_dramas_filter_grid.dart @@ -144,7 +144,7 @@ class _AllDramasFilterGridState extends State { padding: const EdgeInsets.fromLTRB( AppDimens.feedPageHorizontal, 0, - AppDimens.feedPageHorizontal, + AppDimens.allDramasFilterRight, AppDimens.allDramasFilterToGridGap, ), child: Column( @@ -254,7 +254,9 @@ class _AllDramasFilterGridState extends State { child: Text( label, style: TextStyle( - color: selected ? AppColors.textPrimary : AppColors.textTabInactive, + color: selected + ? AppColors.filterChipTextSelected + : AppColors.filterChipTextInactive, fontSize: AppDimens.filterChipFont, fontWeight: selected ? FontWeight.w600 : FontWeight.w400, height: 1, @@ -267,39 +269,41 @@ class _AllDramasFilterGridState extends State { Widget _sortRow(AppLocalizations l10n) { return SizedBox( key: const Key('all-filter-row-3'), - height: AppDimens.filterChipHeight, + height: AppDimens.allDramasFilterButton, child: Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [ - _sortOption( + _chip( key: const Key('all-sort-hot'), label: l10n.hot, selected: !_newest, onTap: () => setState(() => _newest = false), ), const SizedBox(width: AppDimens.filterItemGap), - _sortOption( + _chip( key: const Key('all-sort-new'), label: l10n.newest, selected: _newest, onTap: () => setState(() => _newest = true), ), const Spacer(), - SizedBox.square( - dimension: AppDimens.allDramasFilterIcon, - child: IconButton( + Material( + key: const Key('all-dramas-filter-page-button'), + color: AppColors.filterMenuButton, + shape: const CircleBorder(), + child: InkWell( key: const Key('all-dramas-filter-page'), - tooltip: l10n.filter, - padding: EdgeInsets.zero, - constraints: const BoxConstraints.tightFor( - width: AppDimens.allDramasFilterIcon, - height: AppDimens.allDramasFilterIcon, + customBorder: const CircleBorder(), + onTap: widget.onOpenFilter, + child: const SizedBox.square( + dimension: AppDimens.allDramasFilterButton, + child: Icon( + Icons.filter_list_rounded, + size: AppDimens.allDramasFilterIcon, + color: AppColors.filterMenuIcon, + ), ), - onPressed: widget.onOpenFilter, - color: AppColors.textPrimary, - iconSize: AppDimens.allDramasFilterIcon, - icon: const Icon(Icons.filter_list_rounded), ), ), ], @@ -307,39 +311,6 @@ class _AllDramasFilterGridState extends State { ); } - Widget _sortOption({ - required Key key, - required String label, - required bool selected, - required VoidCallback onTap, - }) { - return GestureDetector( - key: key, - behavior: HitTestBehavior.opaque, - onTap: onTap, - child: SizedBox( - height: AppDimens.filterChipHeight, - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: AppDimens.filterChipHorizontalPadding, - ), - alignment: Alignment.center, - child: Text( - label, - style: TextStyle( - color: selected - ? AppColors.textPrimary - : AppColors.textTabInactive, - fontSize: AppDimens.filterChipFont, - fontWeight: selected ? FontWeight.w700 : FontWeight.w400, - height: 1, - ), - ), - ), - ), - ); - } - List<({String id, String label})> _availableGenres(AppLocalizations l10n) { final definitions = [ (id: 'reversal', label: l10n.reversalFilter, terms: _reversalTerms), diff --git a/test/recommend/recommend_sections_test.dart b/test/recommend/recommend_sections_test.dart index 25775ad..b1299c1 100644 --- a/test/recommend/recommend_sections_test.dart +++ b/test/recommend/recommend_sections_test.dart @@ -260,7 +260,7 @@ void main() { for (var row = 0; row < 4; row++) { final rowRect = tester.getRect(find.byKey(Key('all-filter-row-$row'))); expect(rowRect.left, closeTo(pageRect.left + 14, 0.1)); - expect(rowRect.right, closeTo(pageRect.right - 14, 0.1)); + expect(rowRect.right, closeTo(pageRect.right - 12, 0.1)); } final firstTexts = [ find.descendant( @@ -301,7 +301,7 @@ void main() { } expect( tester.getSize(find.byKey(const Key('all-filter-row-3'))).height, - AppDimens.filterChipHeight, + AppDimens.allDramasFilterButton, ); expect( tester.getRect(find.byKey(const Key('all-dramas-scroll'))).top - @@ -335,6 +335,7 @@ void main() { closeTo(fixedFilterTop, 0.1), ); expect(find.byKey(const Key('all-filter-local')), findsOneWidget); + expect(_textStyle(tester, 'Local').color, AppColors.filterChipTextInactive); expect(find.byKey(const Key('all-filter-subtitles')), findsOneWidget); for (final key in [ 'all-filter-reversal', @@ -376,12 +377,17 @@ void main() { AppDimens.filterItemGap, ); } + expect( + tester.getTopLeft(find.byKey(const Key('all-sort-new'))).dx - + tester.getTopRight(find.byKey(const Key('all-sort-hot'))).dx, + AppDimens.filterItemGap, + ); await tester.tap(find.byKey(const Key('all-filter-local'))); await tester.pumpAndSettle(); expect(find.byKey(const Key('all-dramas-empty')), findsOneWidget); expect(_textStyle(tester, 'Local').fontWeight, FontWeight.w600); expect(_textStyle(tester, 'Local').fontSize, AppDimens.filterChipFont); - expect(_textStyle(tester, 'Local').color, AppColors.textPrimary); + expect(_textStyle(tester, 'Local').color, AppColors.filterChipTextSelected); final selectedChip = tester.widget( find .descendant( @@ -402,8 +408,9 @@ void main() { await tester.pumpAndSettle(); await tester.tap(find.byKey(const Key('all-sort-new'))); await tester.pump(); - expect(_textStyle(tester, 'New').fontWeight, FontWeight.w700); + expect(_textStyle(tester, 'New').fontWeight, FontWeight.w600); expect(_textStyle(tester, 'New').fontSize, AppDimens.filterChipFont); + expect(_textStyle(tester, 'New').color, AppColors.filterChipTextSelected); expect( tester.getSize(find.byKey(const Key('all-sort-new'))).height, AppDimens.filterChipHeight, @@ -421,7 +428,7 @@ void main() { final filterButton = find.byKey(const Key('all-dramas-filter-page')); expect( tester.getSize(filterButton), - const Size.square(AppDimens.allDramasFilterIcon), + const Size.square(AppDimens.allDramasFilterButton), ); expect( tester.getRect(filterButton).right, @@ -430,6 +437,19 @@ void main() { 0.1, ), ); + final filterMaterial = tester.widget( + find.byKey(const Key('all-dramas-filter-page-button')), + ); + expect(filterMaterial.color, AppColors.filterMenuButton); + expect(filterMaterial.shape, const CircleBorder()); + final filterIcon = tester.widget( + find.descendant( + of: filterButton, + matching: find.byIcon(Icons.filter_list_rounded), + ), + ); + expect(filterIcon.size, AppDimens.allDramasFilterIcon); + expect(filterIcon.color, AppColors.filterMenuIcon); await tester.tap(find.byKey(const Key('recommend-tab-playlist'))); await tester.pumpAndSettle();