style: 增强我的页渐变与图标配色
This commit is contained in:
1 parent
647f6afd77
commit
a81bec4d47
6 files changed
+116
-49
No files matched your search
@@ -1260,3 +1260,5 @@ $ flutter test
|
||||
- 页面背景改为暖黑三段纵向渐变,用户区与 VIP 卡布局保持不变。
|
||||
- 行式入口替换为 4 列图标网格,7 个原入口按顺序保留,第 8 格为空占位。
|
||||
- 网格使用 14 边距、半透明深灰底、圆角 12 和仅内部 1px 分隔线;`flutter analyze`:No issues found。
|
||||
- 渐变增强为 `#3A1B0E`/`#1A0C07`/黑色并叠加顶部品牌橙径向光晕,同时移除页面级「我的」标题栏。
|
||||
- 7 个宫格图标分别使用金币金、天蓝、薄荷绿、粉红、紫色、青色和冷灰;`flutter analyze`:No issues found。
|
||||
@@ -84,13 +84,21 @@ abstract final class AppColors {
|
||||
/// 「我的」页卡片与描边。
|
||||
static const mineCard = Color(0xFF16161A);
|
||||
static const mineOutline = Color(0xFF4A4A4A);
|
||||
static const mineGradientTop = Color(0xFF1A0F0A);
|
||||
static const mineGradientMiddle = Color(0xFF0D0908);
|
||||
static const mineGradientTop = Color(0xFF3A1B0E);
|
||||
static const mineGradientMiddle = Color(0xFF1A0C07);
|
||||
static const mineGradientBottom = Color(0xFF000000);
|
||||
static const mineGradientGlow = Color(0x33FF6B2C);
|
||||
static const mineGridSurface = Color(0x99101010);
|
||||
static const mineGridDivider = Color(0xFF2A2A2A);
|
||||
static const mineGridIconSurface = Color(0xFF1C1C1E);
|
||||
static const mineGridLabel = Color(0xFFE6E6EB);
|
||||
static const mineIconWallet = Color(0xFFF5C451);
|
||||
static const mineIconDownloads = Color(0xFF4DA3FF);
|
||||
static const mineIconHistory = Color(0xFF4ADE80);
|
||||
static const mineIconPreferences = Color(0xFFFF6B9A);
|
||||
static const mineIconSupport = Color(0xFFA78BFA);
|
||||
static const mineIconLanguage = Color(0xFF22D3EE);
|
||||
static const mineIconSettings = Color(0xFFA1A1AA);
|
||||
|
||||
/// 次级文字与列表 chevron。
|
||||
static const textPrimary = Color(0xFFFFFFFF);
|
||||
|
||||
@@ -179,7 +179,6 @@ abstract final class AppDimens {
|
||||
|
||||
/// 「我的」页中性视觉。
|
||||
static const double mineCardRadius = 16;
|
||||
static const double minePageTitle = 17;
|
||||
static const double mineSectionTitle = 15;
|
||||
static const double mineAvatar = 56;
|
||||
static const double mineUserName = 20;
|
||||
|
||||
@@ -80,7 +80,6 @@ class _MyPageState extends State<MyPage> {
|
||||
}
|
||||
|
||||
Widget _page(BuildContext context) {
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
final content = DecoratedBox(
|
||||
key: const Key('mine-page-surface'),
|
||||
decoration: const BoxDecoration(
|
||||
@@ -92,18 +91,32 @@ class _MyPageState extends State<MyPage> {
|
||||
AppColors.mineGradientMiddle,
|
||||
AppColors.mineGradientBottom,
|
||||
],
|
||||
stops: [0, 0.48, 1],
|
||||
stops: [0, 0.4, 0.75],
|
||||
),
|
||||
),
|
||||
child: SafeArea(
|
||||
bottom: false,
|
||||
child: Column(
|
||||
children: [
|
||||
_topBar(l10n),
|
||||
Expanded(child: _body(context)),
|
||||
if (!embedded) _bottomNav(),
|
||||
],
|
||||
),
|
||||
child: Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
const DecoratedBox(
|
||||
key: Key('mine-page-glow'),
|
||||
decoration: BoxDecoration(
|
||||
gradient: RadialGradient(
|
||||
center: Alignment(0, -0.95),
|
||||
radius: 0.9,
|
||||
colors: [AppColors.mineGradientGlow, AppColors.transparent],
|
||||
),
|
||||
),
|
||||
),
|
||||
SafeArea(
|
||||
bottom: false,
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(child: _body(context)),
|
||||
if (!embedded) _bottomNav(),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
return AnnotatedRegion<SystemUiOverlayStyle>(
|
||||
@@ -117,29 +130,6 @@ class _MyPageState extends State<MyPage> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _topBar(AppLocalizations l10n) {
|
||||
return SizedBox(
|
||||
height: AppDimens.contentHeaderHeight,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: AppDimens.pageHorizontal,
|
||||
),
|
||||
child: Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
l10n.myTab,
|
||||
style: const TextStyle(
|
||||
fontFamily: 'Outfit',
|
||||
color: AppColors.textPrimary,
|
||||
fontSize: AppDimens.minePageTitle,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _body(BuildContext context) {
|
||||
return ListView(
|
||||
key: const Key('mine-page-scroll'),
|
||||
|
||||
@@ -153,6 +153,7 @@ class MineMenuList extends StatelessWidget {
|
||||
index: 0,
|
||||
actionKey: const Key('mine-wallet'),
|
||||
icon: Icons.account_balance_wallet_outlined,
|
||||
iconColor: AppColors.mineIconWallet,
|
||||
label: l10n.wallet,
|
||||
onTap: () => onOpen(MineDestination.wallet),
|
||||
),
|
||||
@@ -160,6 +161,7 @@ class MineMenuList extends StatelessWidget {
|
||||
index: 1,
|
||||
actionKey: const Key('mine-downloads'),
|
||||
icon: Icons.download_outlined,
|
||||
iconColor: AppColors.mineIconDownloads,
|
||||
label: l10n.offlineDownloads,
|
||||
onTap: () => onOpen(MineDestination.downloads),
|
||||
),
|
||||
@@ -167,6 +169,7 @@ class MineMenuList extends StatelessWidget {
|
||||
index: 2,
|
||||
actionKey: const Key('mine-history'),
|
||||
icon: Icons.history_rounded,
|
||||
iconColor: AppColors.mineIconHistory,
|
||||
label: l10n.watchHistory,
|
||||
onTap: () => onOpen(MineDestination.history),
|
||||
),
|
||||
@@ -174,6 +177,7 @@ class MineMenuList extends StatelessWidget {
|
||||
index: 3,
|
||||
actionKey: const Key('mine-watch-preferences'),
|
||||
icon: Icons.tune_rounded,
|
||||
iconColor: AppColors.mineIconPreferences,
|
||||
label: l10n.watchPreferences,
|
||||
onTap: () => onOpen(MineDestination.preferences),
|
||||
),
|
||||
@@ -185,6 +189,7 @@ class MineMenuList extends StatelessWidget {
|
||||
index: 4,
|
||||
actionKey: const Key('mine-help'),
|
||||
icon: Icons.support_agent_rounded,
|
||||
iconColor: AppColors.mineIconSupport,
|
||||
label: l10n.contactSupport,
|
||||
onTap: () => onOpen(MineDestination.help),
|
||||
),
|
||||
@@ -192,6 +197,7 @@ class MineMenuList extends StatelessWidget {
|
||||
index: 5,
|
||||
actionKey: const Key('mine-language'),
|
||||
icon: Icons.language_rounded,
|
||||
iconColor: AppColors.mineIconLanguage,
|
||||
label: l10n.language,
|
||||
onTap: onLanguage,
|
||||
),
|
||||
@@ -199,6 +205,7 @@ class MineMenuList extends StatelessWidget {
|
||||
index: 6,
|
||||
actionKey: const Key('mine-settings'),
|
||||
icon: Icons.settings_outlined,
|
||||
iconColor: AppColors.mineIconSettings,
|
||||
label: l10n.settings,
|
||||
onTap: () => onOpen(MineDestination.settings),
|
||||
),
|
||||
@@ -215,6 +222,7 @@ class MineMenuList extends StatelessWidget {
|
||||
required int index,
|
||||
Key? actionKey,
|
||||
IconData? icon,
|
||||
Color? iconColor,
|
||||
String? label,
|
||||
VoidCallback? onTap,
|
||||
}) {
|
||||
@@ -237,10 +245,16 @@ class MineMenuList extends StatelessWidget {
|
||||
color: AppColors.mineGridIconSurface,
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(
|
||||
icon,
|
||||
color: AppColors.primary,
|
||||
size: AppDimens.mineGridIcon,
|
||||
child: DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
color: iconColor?.withValues(alpha: 0.08),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(
|
||||
icon,
|
||||
color: iconColor,
|
||||
size: AppDimens.mineGridIcon,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: AppDimens.spaceXs + 2),
|
||||
|
||||
@@ -41,14 +41,6 @@ void main() {
|
||||
expect(find.byKey(const Key('mine-vip')), findsOneWidget);
|
||||
expect(find.byKey(const Key('mine-vip-open')), findsOneWidget);
|
||||
expect(find.byKey(const Key('mine-menu')), findsOneWidget);
|
||||
final title = tester.widget<Text>(
|
||||
find.descendant(
|
||||
of: find.byKey(const Key('mine-page-surface')),
|
||||
matching: find.text('My'),
|
||||
),
|
||||
);
|
||||
expect(title.style?.fontSize, AppDimens.minePageTitle);
|
||||
expect(title.style?.fontWeight, FontWeight.w700);
|
||||
expect(find.byKey(const Key('mine-mini-player')), findsNothing);
|
||||
final surface = tester.widget<DecoratedBox>(
|
||||
find.byKey(const Key('mine-page-surface')),
|
||||
@@ -62,6 +54,25 @@ void main() {
|
||||
AppColors.mineGradientMiddle,
|
||||
AppColors.mineGradientBottom,
|
||||
]);
|
||||
expect(background.stops, const [0, 0.4, 0.75]);
|
||||
expect(
|
||||
find.descendant(
|
||||
of: find.byKey(const Key('mine-page-surface')),
|
||||
matching: find.text('My'),
|
||||
),
|
||||
findsNothing,
|
||||
);
|
||||
final glow = tester.widget<DecoratedBox>(
|
||||
find.byKey(const Key('mine-page-glow')),
|
||||
);
|
||||
final glowDecoration = glow.decoration as BoxDecoration;
|
||||
final radialGlow = glowDecoration.gradient! as RadialGradient;
|
||||
expect(radialGlow.center, const Alignment(0, -0.95));
|
||||
expect(radialGlow.radius, 0.9);
|
||||
expect(radialGlow.colors, const [
|
||||
AppColors.mineGradientGlow,
|
||||
AppColors.transparent,
|
||||
]);
|
||||
for (final oldShortcut in const [
|
||||
Key('mine-watchlist'),
|
||||
Key('mine-history-shortcut'),
|
||||
@@ -83,6 +94,49 @@ void main() {
|
||||
for (final entryKey in entryKeys) {
|
||||
expect(find.byKey(entryKey), findsOneWidget);
|
||||
}
|
||||
const coloredIcons = [
|
||||
(
|
||||
Key('mine-wallet'),
|
||||
Icons.account_balance_wallet_outlined,
|
||||
AppColors.mineIconWallet,
|
||||
),
|
||||
(
|
||||
Key('mine-downloads'),
|
||||
Icons.download_outlined,
|
||||
AppColors.mineIconDownloads,
|
||||
),
|
||||
(Key('mine-history'), Icons.history_rounded, AppColors.mineIconHistory),
|
||||
(
|
||||
Key('mine-watch-preferences'),
|
||||
Icons.tune_rounded,
|
||||
AppColors.mineIconPreferences,
|
||||
),
|
||||
(
|
||||
Key('mine-help'),
|
||||
Icons.support_agent_rounded,
|
||||
AppColors.mineIconSupport,
|
||||
),
|
||||
(
|
||||
Key('mine-language'),
|
||||
Icons.language_rounded,
|
||||
AppColors.mineIconLanguage,
|
||||
),
|
||||
(
|
||||
Key('mine-settings'),
|
||||
Icons.settings_outlined,
|
||||
AppColors.mineIconSettings,
|
||||
),
|
||||
];
|
||||
for (final entry in coloredIcons) {
|
||||
final icon = tester.widget<Icon>(
|
||||
find.descendant(
|
||||
of: find.byKey(entry.$1),
|
||||
matching: find.byIcon(entry.$2),
|
||||
),
|
||||
);
|
||||
expect(icon.color, entry.$3);
|
||||
expect(icon.size, AppDimens.mineGridIcon);
|
||||
}
|
||||
for (var index = 0; index < 8; index++) {
|
||||
expect(find.byKey(Key('mine-menu-cell-$index')), findsOneWidget);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user