如何在Flutter中不使用Stack实现自适应足球场地及球员布局?
自适应足球场地与球员布局实现方案
核心思路
放弃固定图片方案,改用矢量SVG绘制场地+CSS Grid/Flexbox动态排列球员,从根源解决不同阵型导致的两侧高度不一致问题,同时保证全尺寸自适应。
具体实现步骤
1. 用SVG绘制自适应足球场地
SVG是矢量格式,天生支持自适应缩放,不会像位图那样变形。定义好viewBox属性后,场地会自动填充容器空间:
<svg viewBox="0 0 100 60" class="football-pitch"> <!-- 场地边线 --> <rect x="1" y="1" width="98" height="58" fill="#2ecc71" stroke="#fff" stroke-width="0.5"/> <!-- 中线 & 中圈 --> <line x1="50" y1="1" x2="50" y2="59" stroke="#fff" stroke-width="0.5"/> <circle cx="50" cy="30" r="5" stroke="#fff" stroke-width="0.5" fill="none"/> <!-- 双方禁区 --> <rect x="1" y="15" width="12" height="30" fill="none" stroke="#fff" stroke-width="0.5"/> <rect x="87" y="15" width="12" height="30" fill="none" stroke="#fff" stroke-width="0.5"/> <!-- 其他元素(点球点、球门等)可按需添加 --> </svg>
给SVG加基础样式,让它自适应父容器:
.football-pitch { width: 100%; max-width: 800px; margin: 0 auto; }
2. 用CSS Grid实现球员自适应排列
把场地两侧的球员区域设为Grid容器,根据阵型的行数动态分配行高,确保两侧高度完全对齐:
<div class="pitch-container"> <div class="team team-home" data-formation="4-3-3"></div> <svg class="football-pitch">...</svg> <div class="team team-away" data-formation="3-4-2-1"></div> </div>
.pitch-container { display: flex; align-items: stretch; /* 强制两侧球队容器高度一致 */ gap: 10px; padding: 20px; } .team { display: grid; gap: 8px; align-items: center; } /* 动态生成的阵型样式,比如4-3-3对应3行 */ .team[data-formation="4-3-3"] { grid-template-rows: repeat(3, 1fr); } .team[data-formation="3-4-2-1"] { grid-template-rows: repeat(4, 1fr); }
3. JS动态渲染球员
根据阵型数据生成对应数量的球员卡片,自动填充到Grid容器中:
// 阵型数据:键是阵型标识,值是每行球员数量 const formations = { "4-3-3": [4, 3, 3], "3-4-2-1": [3, 4, 2, 1] }; function renderTeam(teamEl, formationKey) { const playerCounts = formations[formationKey]; teamEl.innerHTML = ""; playerCounts.forEach(count => { const row = document.createElement("div"); row.style.display = "flex"; row.style.justifyContent = "center"; row.style.gap = "6px"; for(let i=0; i<count; i++) { const player = document.createElement("div"); player.className = "player"; player.textContent = "10"; // 替换为球员号码/姓名 row.appendChild(player); } teamEl.appendChild(row); }); } // 渲染两支球队 renderTeam(document.querySelector(".team-home"), "4-3-3"); renderTeam(document.querySelector(".team-away"), "3-4-2-1");
给球员卡片加基础样式:
.player { width: 32px; height: 32px; border-radius: 50%; background: #fff; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: bold; }
关键优势
- 完全自适应:不管是桌面端还是移动端,场地和球员布局都会自动适配容器尺寸
- 阵型兼容:支持任意阵型,只需在
formations对象中添加对应数据即可 - 高度对齐:通过
align-items: stretch和Grid的等分行高,强制两侧球队区域高度一致
内容的提问来源于stack exchange,提问作者Alifarhad Ali
相关产品推荐
相关产品推荐

