feat(flutter): 应用浅色暖橙视觉主题

This commit is contained in:
Zhou Weidong committed 2026-10-20 10:15:03 +08:00
1 parent 0d2367431d
commit 634b63e16c
56 files changed
+941 -409

No files matched your search

+100 -22
View File
@@ -7,7 +7,7 @@ import 'package:flutter/material.dart';
import '../theme/app_colors.dart';
import '../theme/app_dimens.dart';
/// One destination rendered by [AppBottomNav].
/// 底部导航普通目的地。
class AppBottomNavItem {
const AppBottomNavItem({
required this.tabKey,
@@ -26,41 +26,69 @@ class AppBottomNavItem {
final bool selected;
}
/// Shared bottom navigation used by the root shell and standalone tabs.
/// 底部导航中央操作按钮。
class AppBottomNavCenterAction {
const AppBottomNavCenterAction({
required this.label,
required this.onTap,
this.key = const Key('nav-center-action'),
});
final Key key;
final String label;
final VoidCallback onTap;
}
/// 全局五槽底部导航。
class AppBottomNav extends StatelessWidget {
const AppBottomNav({
super.key,
required this.items,
this.centerAction,
this.backgroundColor = AppColors.bar,
this.barKey,
});
final List<AppBottomNavItem> items;
final AppBottomNavCenterAction? centerAction;
final Color backgroundColor;
final Key? barKey;
@override
Widget build(BuildContext context) => ClipRect(
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 20, sigmaY: 20),
child: SafeArea(
top: false,
child: Container(
key: barKey,
height: AppDimens.navHeight,
decoration: BoxDecoration(
color: backgroundColor.withValues(alpha: 0.95),
border: const Border(
top: BorderSide(color: AppColors.outlineVariantDark),
Widget build(BuildContext context) {
final action = centerAction;
return ClipRect(
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 20, sigmaY: 20),
child: SafeArea(
top: false,
child: Container(
key: barKey,
height: AppDimens.navHeight,
decoration: BoxDecoration(
color: backgroundColor.withValues(alpha: 0.95),
border: const Border(top: BorderSide(color: AppColors.border)),
),
),
child: Row(
children: [for (final item in items) _NavDestination(item: item)],
child: action == null
? Row(
children: [
for (final item in items) _NavDestination(item: item),
],
)
: Row(
children: [
for (final item in items.take(2))
_NavDestination(item: item),
Expanded(child: _CenterDestination(action: action)),
for (final item in items.skip(2))
_NavDestination(item: item),
],
),
),
),
),
),
);
);
}
}
class _NavDestination extends StatelessWidget {
@@ -78,7 +106,7 @@ class _NavDestination extends StatelessWidget {
key: item.tabKey,
onTap: item.onTap,
child: ConstrainedBox(
constraints: const BoxConstraints(minHeight: 48),
constraints: const BoxConstraints(minHeight: AppDimens.navHeight),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
@@ -91,7 +119,7 @@ class _NavDestination extends StatelessWidget {
size: AppDimens.navIcon,
color: item.selected
? AppColors.blue
: Colors.white.withValues(alpha: 0.45),
: AppColors.navUnselected,
),
),
const SizedBox(height: 2),
@@ -104,7 +132,7 @@ class _NavDestination extends StatelessWidget {
fontWeight: item.selected ? FontWeight.w700 : FontWeight.w500,
color: item.selected
? AppColors.blue
: Colors.white.withValues(alpha: 0.45),
: AppColors.navUnselected,
letterSpacing: 0,
),
),
@@ -115,3 +143,53 @@ class _NavDestination extends StatelessWidget {
),
);
}
class _CenterDestination extends StatelessWidget {
const _CenterDestination({required this.action});
final AppBottomNavCenterAction action;
@override
Widget build(BuildContext context) {
return Center(
child: Semantics(
button: true,
label: action.label,
child: Material(
color: Colors.transparent,
shape: const CircleBorder(),
clipBehavior: Clip.antiAlias,
child: Ink(
width: AppDimens.navCenter,
height: AppDimens.navCenter,
decoration: const BoxDecoration(
shape: BoxShape.circle,
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [AppColors.navCenterStart, AppColors.navCenterEnd],
),
boxShadow: [
BoxShadow(
color: AppColors.navCenterShadow,
blurRadius: 14,
offset: Offset(0, 5),
),
],
),
child: InkWell(
key: action.key,
customBorder: const CircleBorder(),
onTap: action.onTap,
child: const Icon(
Icons.add_rounded,
color: AppColors.onPrimary,
size: AppDimens.navCenterIcon,
),
),
),
),
),
);
}
}
+2 -2
View File
@@ -7,7 +7,7 @@ import 'package:flutter/material.dart';
import '../theme/app_colors.dart';
import '../theme/app_dimens.dart';
/// Dark glass surface used by the home info card and floating controls.
/// 首页信息卡与浮层控件使用的浅色玻璃面板。
class GlassPanel extends StatelessWidget {
const GlassPanel({
super.key,
@@ -38,7 +38,7 @@ class GlassPanel extends StatelessWidget {
const LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [Color(0x24FFFFFF), Color(0x0DFFFFFF)],
colors: [Color(0xE6FFFFFF), Color(0xB3FFFDFB)],
),
),
child: Padding(padding: padding ?? EdgeInsets.zero, child: child),