refactor: 重构多个页面布局与样式,修复溢出问题

调整了勘测任务页、项目页的顶部栏样式,优化了底部导航栏的底部间距
重构客户卡片布局,使用 IntrinsicHeight 避免高度溢出,添加 FittedBox 防止文本溢出
统一了部分代码的换行格式,提升代码可读性
This commit is contained in:
andyesfly committed 2026-10-02 17:54:18 +08:00
1 parent f61b7bf90b
commit e14d371cc8
4 files changed
+53 -49

No files matched your search

@@ -136,6 +136,7 @@ class _CustomerTabState extends ConsumerState<CustomerTab> {
trailingColor: AppColors.primary, trailingColor: AppColors.primary,
), ),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
_buildPageHead(), _buildPageHead(),
_buildSearchBar(), _buildSearchBar(),
@@ -297,13 +298,15 @@ class _CustomerTabState extends ConsumerState<CustomerTab> {
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
margin: const EdgeInsets.only(bottom: 12), margin: const EdgeInsets.only(bottom: 12),
onTap: () => _goDetail(c), onTap: () => _goDetail(c),
child: Stack( // 对应源项目 `.customer-card { display:flex }`:主内容与右侧编号面板是并排的
// 两个子项,卡片高度取两者较大值。IntrinsicHeight 让两侧等高,避免右侧
// 内容(编号换行 + 操作按钮)撑出卡片导致 RenderFlex 溢出。
child: IntrinsicHeight(
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
// 左侧状态色条 / 右侧编号面板均贴边,圆角按卡片圆角裁出 // 左侧状态色条,圆角按卡片圆角裁出
Positioned( SizedBox(
left: 0,
top: 0,
bottom: 0,
width: 4, width: 4,
child: DecoratedBox( child: DecoratedBox(
decoration: BoxDecoration( decoration: BoxDecoration(
@@ -314,22 +317,7 @@ class _CustomerTabState extends ConsumerState<CustomerTab> {
), ),
), ),
), ),
const Positioned( Expanded(
right: 0,
top: 0,
bottom: 0,
width: 86,
child: DecoratedBox(
decoration: BoxDecoration(
color: AppColors.surfaceBright,
borderRadius: BorderRadius.horizontal(
right: Radius.circular(AppRadius.lg),
),
),
),
),
Padding(
padding: const EdgeInsets.only(left: 4, right: 86),
child: Padding( child: Padding(
padding: const EdgeInsets.all(14), padding: const EdgeInsets.all(14),
child: Column( child: Column(
@@ -362,7 +350,11 @@ class _CustomerTabState extends ConsumerState<CustomerTab> {
), ),
), ),
const SizedBox(width: 6), const SizedBox(width: 6),
const XIcon('more', size: 20, color: AppColors.textMuted), const XIcon(
'more',
size: 20,
color: AppColors.textMuted,
),
], ],
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
@@ -382,7 +374,11 @@ class _CustomerTabState extends ConsumerState<CustomerTab> {
), ),
), ),
const SizedBox(width: 16), const SizedBox(width: 16),
const XIcon('person', size: 16, color: AppColors.textMuted), const XIcon(
'person',
size: 16,
color: AppColors.textMuted,
),
const SizedBox(width: 4), const SizedBox(width: 4),
Text( Text(
c.contactPerson.isEmpty ? '-' : c.contactPerson, c.contactPerson.isEmpty ? '-' : c.contactPerson,
@@ -397,13 +393,16 @@ class _CustomerTabState extends ConsumerState<CustomerTab> {
), ),
), ),
), ),
Positioned( // 右侧编号面板,圆角按卡片圆角裁出
right: 0, Container(
top: 0,
bottom: 0,
width: 86, width: 86,
child: Padding(
padding: const EdgeInsets.all(12), padding: const EdgeInsets.all(12),
decoration: const BoxDecoration(
color: AppColors.surfaceBright,
borderRadius: BorderRadius.horizontal(
right: Radius.circular(AppRadius.lg),
),
),
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@@ -432,8 +431,15 @@ class _CustomerTabState extends ConsumerState<CustomerTab> {
), ),
decoration: BoxDecoration( decoration: BoxDecoration(
color: const Color(0x1A712AE2), color: const Color(0x1A712AE2),
borderRadius: BorderRadius.circular(AppRadius.regular), borderRadius: BorderRadius.circular(
AppRadius.regular,
), ),
),
// '跟进展' 等较长文案在 62px 内容宽内会横向溢出,
// 等比缩放兜底,避免 RenderFlex 溢出条纹。
child: FittedBox(
fit: BoxFit.scaleDown,
alignment: Alignment.centerLeft,
child: Row( child: Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
@@ -453,13 +459,14 @@ class _CustomerTabState extends ConsumerState<CustomerTab> {
), ),
), ),
), ),
),
], ],
], ],
), ),
), ),
),
], ],
), ),
),
); );
} }
} }
@@ -131,11 +131,9 @@ class _ProjectTabState extends ConsumerState<ProjectTab> {
}); });
return XPageShell( return XPageShell(
topBar: XTopBar.brand( topBar: XTopBar.brand(title: '鑫潼智电', trailingColor: AppColors.primary),
title: '鑫潼智电',
trailingColor: AppColors.primary,
),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
_buildPageHead(), _buildPageHead(),
_buildSearchBar(), _buildSearchBar(),
@@ -297,7 +295,11 @@ class _ProjectTabState extends ConsumerState<ProjectTab> {
), ),
), ),
const SizedBox(width: 12), const SizedBox(width: 12),
const XIcon('clock', size: 15, color: AppColors.textMuted), const XIcon(
'clock',
size: 15,
color: AppColors.textMuted,
),
const SizedBox(width: 4), const SizedBox(width: 4),
Text( Text(
formatDate(p.registerTime), formatDate(p.registerTime),
@@ -50,7 +50,7 @@ class _SurveyListPageState extends ConsumerState<SurveyListPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return XPageShell( return XPageShell(
topBar: XTopBar.brand(title: '勘测任务'), topBar: XTopBar.nav(title: '勘测任务', onBack: () => context.pop()),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
@@ -156,7 +156,10 @@ class _SurveyListPageState extends ConsumerState<SurveyListPage> {
Expanded( Expanded(
child: Text( child: Text(
text, text,
style: const TextStyle(fontSize: 14, color: AppColors.onSurfaceVariant), style: const TextStyle(
fontSize: 14,
color: AppColors.onSurfaceVariant,
),
), ),
), ),
], ],
+3 -11
View File
@@ -7,14 +7,10 @@ import 'x_icon.dart';
/// 底部悬浮胶囊导航,对应 `components/XBottomNav.vue`。 /// 底部悬浮胶囊导航,对应 `components/XBottomNav.vue`。
/// ///
/// 距屏幕底部 12px(再叠加安全区),高 56,四周内边距 5, /// 距屏幕底部 4px(再叠加安全区),高 56,四周内边距 5,
/// 四个 tab 等宽均分;激活项铺满所在分格。 /// 四个 tab 等宽均分;激活项铺满所在分格。
class XBottomNav extends StatelessWidget { class XBottomNav extends StatelessWidget {
const XBottomNav({ const XBottomNav({super.key, required this.current, required this.onChanged});
super.key,
required this.current,
required this.onChanged,
});
final String current; final String current;
final ValueChanged<String> onChanged; final ValueChanged<String> onChanged;
@@ -31,11 +27,7 @@ class XBottomNav extends StatelessWidget {
final bottomInset = MediaQuery.paddingOf(context).bottom; final bottomInset = MediaQuery.paddingOf(context).bottom;
return Padding( return Padding(
padding: EdgeInsets.only( padding: EdgeInsets.only(left: 16, right: 16, bottom: 4 + bottomInset),
left: 16,
right: 16,
bottom: 12 + bottomInset,
),
child: Container( child: Container(
height: 56, height: 56,
padding: const EdgeInsets.all(5), padding: const EdgeInsets.all(5),