fix: 欢迎卡片UI优化 + 蓝牙录入按钮 + 多处修复

- 欢迎卡片:去掉白框圆角错位、图片满宽、按钮去箭头改圆角居中
- 渐变actionOutlineGradient改紫蓝双色循环
- 新增健康Agent"蓝牙录入"按钮→蓝牙设备页
- "查看健康情况"改名"健康概览"
- 饮食编辑框删除bug修复(控制器缓存)
- 启动脚本加adb reverse自动转发
- 登录闪屏修复
This commit is contained in:
MingNian
2026-06-17 10:58:59 +08:00
parent 9279b7e283
commit 4f1ad82345
28 changed files with 1641 additions and 1098 deletions

View File

@@ -23,7 +23,9 @@ class GradientBorderButton extends StatelessWidget {
return Container(
height: height,
decoration: BoxDecoration(
gradient: isSuccess ? AppColors.primaryGradient : AppColors.primaryGradient,
gradient: isSuccess
? AppColors.calmHealthGradient
: AppColors.primaryGradient,
borderRadius: BorderRadius.circular(14),
boxShadow: AppColors.buttonShadow,
),
@@ -78,9 +80,10 @@ class CardActionButton extends StatelessWidget {
child: Container(
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 10),
decoration: BoxDecoration(
color: AppColors.cardInner,
gradient: AppColors.surfaceGradient,
borderRadius: BorderRadius.circular(12),
border: Border.all(color: AppColors.borderLight),
boxShadow: AppColors.cardShadowLight,
),
child: Row(
mainAxisSize: MainAxisSize.min,
@@ -109,11 +112,19 @@ class SwipeDeleteTile extends StatefulWidget {
final VoidCallback onDelete;
final VoidCallback? onTap;
final EdgeInsetsGeometry margin;
const SwipeDeleteTile({super.key, required this.child, required this.onDelete, this.onTap, this.margin = const EdgeInsets.symmetric(horizontal: 16, vertical: 4)});
@override State<SwipeDeleteTile> createState() => _SwipeDeleteTileState();
const SwipeDeleteTile({
super.key,
required this.child,
required this.onDelete,
this.onTap,
this.margin = const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
});
@override
State<SwipeDeleteTile> createState() => _SwipeDeleteTileState();
}
class _SwipeDeleteTileState extends State<SwipeDeleteTile> with SingleTickerProviderStateMixin {
class _SwipeDeleteTileState extends State<SwipeDeleteTile>
with SingleTickerProviderStateMixin {
double _dx = 0;
static const _maxSlide = 80.0;
static const _threshold = 24.0; // 30% of 80
@@ -130,31 +141,53 @@ class _SwipeDeleteTileState extends State<SwipeDeleteTile> with SingleTickerProv
}
}
@override Widget build(BuildContext context) {
@override
Widget build(BuildContext context) {
final isSwiped = _dx < 0;
return Padding(
padding: widget.margin,
child: Stack(children: [
Positioned.fill(child: Container(
decoration: BoxDecoration(color: AppColors.error, borderRadius: BorderRadius.circular(16)),
child: const Align(
alignment: Alignment.centerRight,
child: Padding(padding: EdgeInsets.only(right: 20), child: Icon(Icons.delete_outline, color: AppColors.textOnGradient, size: 28)),
child: Stack(
children: [
Positioned.fill(
child: Container(
decoration: BoxDecoration(
color: AppColors.error,
borderRadius: BorderRadius.circular(16),
),
child: const Align(
alignment: Alignment.centerRight,
child: Padding(
padding: EdgeInsets.only(right: 20),
child: Icon(
Icons.delete_outline,
color: AppColors.textOnGradient,
size: 28,
),
),
),
),
),
)),
GestureDetector(
behavior: isSwiped ? HitTestBehavior.opaque : HitTestBehavior.deferToChild,
onTap: isSwiped ? () { widget.onDelete(); setState(() => _dx = 0); } : widget.onTap,
onHorizontalDragUpdate: _onDragUpdate,
onHorizontalDragEnd: _onDragEnd,
child: Transform.translate(
offset: Offset(_dx, 0),
child: isSwiped
? AbsorbPointer(absorbing: true, child: widget.child)
: widget.child,
GestureDetector(
behavior: isSwiped
? HitTestBehavior.opaque
: HitTestBehavior.deferToChild,
onTap: isSwiped
? () {
widget.onDelete();
setState(() => _dx = 0);
}
: widget.onTap,
onHorizontalDragUpdate: _onDragUpdate,
onHorizontalDragEnd: _onDragEnd,
child: Transform.translate(
offset: Offset(_dx, 0),
child: isSwiped
? AbsorbPointer(absorbing: true, child: widget.child)
: widget.child,
),
),
),
]),
],
),
);
}
}
@@ -180,14 +213,12 @@ class IconBox extends StatelessWidget {
width: size,
height: size,
decoration: BoxDecoration(
color: backgroundColor ?? AppColors.iconBg,
gradient: backgroundColor == null ? AppColors.calmHealthGradient : null,
color: backgroundColor,
borderRadius: BorderRadius.circular(size / 3),
boxShadow: AppColors.cardShadowLight,
),
child: Icon(
icon,
size: size * 0.55,
color: iconColor ?? AppColors.primary,
),
child: Icon(icon, size: size * 0.55, color: iconColor ?? Colors.white),
);
}
}