You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter分段控件实现求助:内阴影与边框间距问题

解决你的分段控件问题:内阴影+选项间距

先给你调整后的完整可运行代码,再分点说明修改细节:

// 假设你已提前定义 isSelected、black3、primaryGradient 这些变量
Row(
  mainAxisSize: MainAxisSize.min,
  children: [
    // 第一个选项:Events
    Container(
      width: MediaQuery.of(context).size.width * 0.3,
      margin: const EdgeInsets.only(right: 8), // 新增:选项间的间距
      decoration: ShapeDecoration(
        color: isSelected[0] ? null : black3,
        gradient: isSelected[0] ? primaryGradient : null,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(12),
        ),
        // 内阴影核心修改:添加 inset: true
        boxShadow: isSelected[0]
            ? [
                BoxShadow(
                  color: Colors.black.withOpacity(0.4),
                  offset: const Offset(2, 2),
                  blurRadius: 4,
                  inset: true, // 开启内阴影
                ),
                BoxShadow(
                  color: Colors.white.withOpacity(0.2),
                  offset: const Offset(-2, -2),
                  blurRadius: 4,
                  inset: true, // 开启内阴影
                ),
              ]
            : null,
      ),
      padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12), // 新增垂直padding优化高度
      child: const Center(child: Text('Events')),
    ),
    // 第二个选项:Bars
    Container(
      width: MediaQuery.of(context).size.width * 0.3,
      decoration: ShapeDecoration(
        color: isSelected[1] ? null : black3,
        gradient: isSelected[1] ? primaryGradient : null,
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(12),
        ),
        boxShadow: isSelected[1]
            ? [
                BoxShadow(
                  color: Colors.black.withOpacity(0.4),
                  offset: const Offset(2, 2),
                  blurRadius: 4,
                  inset: true,
                ),
                BoxShadow(
                  color: Colors.white.withOpacity(0.2),
                  offset: const Offset(-2, -2),
                  blurRadius: 4,
                  inset: true,
                ),
              ]
            : null,
      ),
      padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
      child: const Center(child: Text('Bars')),
    ),
  ],
)

1. 选项间距怎么加?

两种简单方法选一种就行:

  • 给第一个容器加margin: const EdgeInsets.only(right: 8),直接让它和右边的容器拉开距离,数值可以根据视觉需求调整(比如6、10)。
  • 在两个容器中间插入const SizedBox(width: 8),效果完全一致,代码结构更直观:
    children: [
      Container(/*第一个选项*/),
      const SizedBox(width: 8), // 间距
      Container(/*第二个选项*/),
    ]
    

2. 内阴影(3D胶囊效果)怎么实现?

你之前的代码只差一个关键参数:inset: true。Flutter的BoxShadow默认是外阴影,加上这个参数后,阴影会渲染在容器内部,正好模拟出3D凹陷/凸起的效果。

另外可以微调参数优化质感:

  • 右下的深色内阴影:模拟凹陷的阴影,增强立体感
  • 左上的浅色内阴影:模拟高光,让凸起效果更自然
  • 如果觉得阴影太突兀,可以降低opacity(比如0.3)或者缩小blurRadius(比如3),慢慢试出你想要的效果。

额外小优化:

  • 给容器添加垂直方向的padding(vertical:12),避免控件太扁,视觉比例更协调。
  • 把borderRadius统一写成BorderRadius.circular(12),不用拆分only,代码更简洁。

内容的提问来源于stack exchange,提问作者Florian Feiler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 23:33:10