fix(mobile): 修复火柴人组件布局错误,避免嵌套Stack
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
0623169d19
commit
27bee6d7f1
|
|
@ -188,9 +188,8 @@ class _StickmanRaceWidgetState extends State<StickmanRaceWidget>
|
|||
builder: (context, constraints) {
|
||||
final containerWidth = constraints.maxWidth;
|
||||
|
||||
return Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
// 收集所有 Positioned widgets
|
||||
final List<Widget> children = [
|
||||
// 背景赛道线
|
||||
Positioned.fill(
|
||||
child: CustomPaint(
|
||||
|
|
@ -199,11 +198,12 @@ class _StickmanRaceWidgetState extends State<StickmanRaceWidget>
|
|||
),
|
||||
),
|
||||
),
|
||||
];
|
||||
|
||||
// 每个跑道的终点红旗
|
||||
...List.generate(trackCount, (index) {
|
||||
// 添加每个跑道的终点红旗
|
||||
for (int index = 0; index < trackCount; index++) {
|
||||
final verticalPosition = index * trackHeight + 10 + trackHeight / 2 - 16;
|
||||
return Positioned(
|
||||
children.add(Positioned(
|
||||
right: 8,
|
||||
top: verticalPosition,
|
||||
child: const Icon(
|
||||
|
|
@ -211,24 +211,32 @@ class _StickmanRaceWidgetState extends State<StickmanRaceWidget>
|
|||
color: Colors.red,
|
||||
size: 24,
|
||||
),
|
||||
);
|
||||
}),
|
||||
));
|
||||
}
|
||||
|
||||
// 火柴人们
|
||||
...sortedRankings.asMap().entries.map((entry) {
|
||||
final index = entry.key;
|
||||
final data = entry.value;
|
||||
return _buildStickman(data, index, sortedRankings.length, raceTrackHeight, containerWidth);
|
||||
}),
|
||||
],
|
||||
// 添加火柴人们(昵称和火柴人分开添加)
|
||||
for (int index = 0; index < sortedRankings.length; index++) {
|
||||
final data = sortedRankings[index];
|
||||
final widgets = _buildStickmanWidgets(data, index, sortedRankings.length, raceTrackHeight, containerWidth);
|
||||
children.addAll(widgets);
|
||||
}
|
||||
|
||||
return AnimatedBuilder(
|
||||
animation: _bounceController,
|
||||
builder: (context, child) {
|
||||
return Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: children,
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// 构建单个火柴人
|
||||
Widget _buildStickman(StickmanRankingData data, int rank, int total, double raceTrackHeight, double containerWidth) {
|
||||
/// 构建单个火柴人的所有 Positioned widgets
|
||||
List<Widget> _buildStickmanWidgets(StickmanRankingData data, int rank, int total, double raceTrackHeight, double containerWidth) {
|
||||
// 进度 (0.0 - 1.0)
|
||||
final progress = data.progress;
|
||||
|
||||
|
|
@ -237,22 +245,16 @@ class _StickmanRaceWidgetState extends State<StickmanRaceWidget>
|
|||
final trackHeight = usableHeight / total;
|
||||
final verticalPosition = rank * trackHeight + 10;
|
||||
|
||||
// 火柴人列宽度约50(数量标签maxWidth:60,但实际更窄)
|
||||
// 红旗: right=8, width=24, 所以红旗左边 = containerWidth - 32
|
||||
// 火柴人停在红旗左边时: stickmanLeft + 50 = containerWidth - 32
|
||||
// 所以 endX = containerWidth - 82
|
||||
// 简单计算:
|
||||
// 起点 = 70 (昵称区域右边)
|
||||
// 终点 = 红旗左边位置 - 火柴人宽度 = (containerWidth - 32) - 50 = containerWidth - 82
|
||||
const double startX = 70.0;
|
||||
final double endX = containerWidth - 82.0;
|
||||
final double stickmanLeft = startX + (endX - startX) * progress;
|
||||
|
||||
return AnimatedBuilder(
|
||||
animation: _bounceController,
|
||||
builder: (context, child) {
|
||||
final bounce = _bounceController.value * 3;
|
||||
|
||||
return Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
return [
|
||||
// 昵称标签 - 固定在左边
|
||||
Positioned(
|
||||
left: 0,
|
||||
|
|
@ -327,10 +329,7 @@ class _StickmanRaceWidgetState extends State<StickmanRaceWidget>
|
|||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
];
|
||||
}
|
||||
|
||||
/// 构建进度条
|
||||
|
|
|
|||
Loading…
Reference in New Issue