merge: 稳定二级标签切换布局

This commit is contained in:
Zhou Weidong committed 2026-10-22 18:41:05 +08:00
commit 62cb4d9809
4 files changed
+33 -37

No files matched your search

+1 -1
View File
@@ -1111,7 +1111,7 @@ $ flutter test
## 2026-10-22 首页布局对齐修正
- 一级分类未选 18/w400、选中 20/w700;二级 chips 与 26 高透明三线筛选图标仅在精选显示。
- 一级分类未选 18/w400、选中 20/w700;二级 chips 间距 24、15/w600,并以稳定 AnimatedContainer 切换。
- 四类卡片去底板/描边,封面统一 3:4、8 圆角、行距 10、封底标题间距 6;状态角标为右上角紧凑异形丝带。
- 标题下方恢复左对齐题材文字,使用 `|` 分隔、灰色小字,与封面状态角标保持独立。
- 首页搜索栏到一级、一级到二级、二级到网格间距为 8/8/10;非精选 tab 直接以 10 衔接网格。
+4 -1
View File
@@ -111,12 +111,15 @@ abstract final class AppDimens {
static const double homeSecondaryTagHeight = 26;
static const double homeSecondaryTagHorizontalPadding = 10;
static const double homeSecondaryTagRadius = 13;
static const Duration homeSecondaryTagAnimationDuration = Duration(
milliseconds: 150,
);
static const double homeSecondaryFilterGap = 8;
static const double homeSecondaryFilterVisualSize = 26;
static const double homeSecondaryFilterIcon = 16;
static const double homeSecondaryFilterStroke = 1.7;
static const double homePrimaryCategoryGap = 24;
static const double homeSecondaryTagGap = 14;
static const double homeSecondaryTagGap = 24;
static const double homeSearchTopGap = 0;
static const double homeSearchPrimaryGap = 8;
static const double homePrimarySecondaryGap = 8;
+17 -21
View File
@@ -366,10 +366,10 @@ class HomeGridHeader extends StatelessWidget {
final selected = selectedTag == tag.id;
final label = Text(
tag.label,
style: TextStyle(
style: const TextStyle(
color: selected ? AppColors.navSelected : AppColors.textTertiary,
fontSize: AppDimens.homeSecondaryTagFont,
fontWeight: selected ? FontWeight.w600 : FontWeight.w400,
fontWeight: FontWeight.w600,
letterSpacing: 0,
),
);
@@ -377,25 +377,21 @@ class HomeGridHeader extends StatelessWidget {
key: Key('home-tag-${tag.id}'),
borderRadius: BorderRadius.circular(AppDimens.pillRadius),
onTap: () => onTagSelected(selected ? null : tag.id),
child: selected
? Container(
height: AppDimens.homeSecondaryTagHeight,
padding: const EdgeInsets.symmetric(
horizontal: AppDimens.homeSecondaryTagHorizontalPadding,
),
alignment: Alignment.center,
decoration: BoxDecoration(
color: AppColors.contentSurface,
borderRadius: BorderRadius.circular(
AppDimens.homeSecondaryTagRadius,
),
),
child: label,
)
: SizedBox(
height: AppDimens.homeSecondaryTagHeight,
child: Align(alignment: Alignment.centerLeft, child: label),
),
child: AnimatedContainer(
key: Key('home-tag-animated-${tag.id}'),
duration: AppDimens.homeSecondaryTagAnimationDuration,
curve: Curves.easeOut,
height: AppDimens.homeSecondaryTagHeight,
padding: const EdgeInsets.symmetric(
horizontal: AppDimens.homeSecondaryTagHorizontalPadding,
),
alignment: Alignment.center,
decoration: BoxDecoration(
color: selected ? AppColors.contentSurface : AppColors.transparent,
borderRadius: BorderRadius.circular(AppDimens.homeSecondaryTagRadius),
),
child: label,
),
);
}
}
+11 -14
View File
@@ -167,14 +167,14 @@ void main() {
),
);
expect(secondaryTag.style?.fontSize, AppDimens.homeSecondaryTagFont);
expect(secondaryTag.style?.fontWeight, FontWeight.w400);
expect(secondaryTag.style?.fontWeight, FontWeight.w600);
expect(secondaryTag.style?.color, AppColors.textTertiary);
final unselectedTagChip = tester.widget<AnimatedContainer>(
find.byKey(const Key('home-tag-animated-hot')),
);
expect(
find.descendant(
of: find.byKey(const Key('home-tag-hot')),
matching: find.byType(Container),
),
findsNothing,
(unselectedTagChip.decoration! as BoxDecoration).color,
AppColors.transparent,
);
final primaryStart = tester.getTopLeft(find.text('Featured'));
final pageStart = tester.getTopLeft(searchBox);
@@ -183,23 +183,20 @@ void main() {
tester.getTopLeft(find.text('New')).dx -
tester.getBottomRight(find.text('Featured')).dx;
expect(primaryGap, closeTo(AppDimens.homePrimaryCategoryGap, 0.1));
final tagStart = tester.getTopLeft(find.text('Hot'));
final tagStart = tester.getTopLeft(find.byKey(const Key('home-tag-hot')));
expect(tagStart.dx, pageStart.dx);
expect(
tester.getSize(find.byKey(const Key('home-tag-hot'))).height,
AppDimens.homeSecondaryTagHeight,
);
final tagGap =
tester.getTopLeft(find.text('Uplifting')).dx -
tester.getBottomRight(find.text('Hot')).dx;
tester.getTopLeft(find.byKey(const Key('home-tag-uplifting'))).dx -
tester.getBottomRight(find.byKey(const Key('home-tag-hot'))).dx;
expect(tagGap, closeTo(AppDimens.homeSecondaryTagGap, 0.1));
await tester.tap(find.byKey(const Key('home-tag-hot')));
await tester.pump();
final selectedTagChip = tester.widget<Container>(
find.descendant(
of: find.byKey(const Key('home-tag-hot')),
matching: find.byType(Container),
),
final selectedTagChip = tester.widget<AnimatedContainer>(
find.byKey(const Key('home-tag-animated-hot')),
);
expect(
(selectedTagChip.decoration! as BoxDecoration).color,