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

Flutter中如何为SegmentedButton添加内外阴影?

解决Flutter SegmentedButton的内外阴影问题

你之前用Container嵌套出现间距,是因为SegmentedButton默认带内边距且没有完全填充容器。下面是调整后的方案,可同时实现内外阴影效果:

核心思路

  1. 用Stack嵌套两层Container:外层负责外阴影,内层模拟内阴影
  2. 让SegmentedButton完全填充容器,去掉默认边距,背景设为透明以露出内层的内阴影
  3. 单独调整每个按钮段的内容边距,避免内容贴边

修改后的代码

Stack(
  alignment: Alignment.center,
  children: [
    // 内层:模拟内阴影
    Container(
      width: double.infinity,
      height: 52, // 自定义按钮高度
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(15),
        boxShadow: const [
          BoxShadow(
            color: Colors.grey.shade200,
            offset: Offset(0, 1),
            blurRadius: 2,
            spreadRadius: 0,
            blurStyle: BlurStyle.inner, // 内阴影关键属性
          ),
        ],
        color: Colors.white, // 按钮基础底色
      ),
    ),
    // 外层:外阴影 + SegmentedButton
    Container(
      width: double.infinity,
      height: 52,
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(15),
        boxShadow: [
          const BoxShadow(
            color: Colors.black12,
            offset: Offset(3.0, 3.0),
            blurRadius: 2,
            spreadRadius: 1.0,
          ),
          BoxShadow(
            color: Colors.grey.shade800,
            offset: const Offset(-1, -1),
            blurRadius: 1,
            spreadRadius: 0.1,
          ),
        ],
      ),
      child: SegmentedButton<Graphendarstellung>(
        style: SegmentedButton.styleFrom(
          selectedBackgroundColor: Colors.orange,
          side: BorderSide.none,
          padding: EdgeInsets.zero, // 去掉默认内边距
          minimumSize: const Size(double.infinity, 52), // 完全填充容器高度
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(15),
          ),
          backgroundColor: Colors.transparent, // 透明背景,露出内层内阴影
        ),
        segments: <ButtonSegment<Graphendarstellung>>[
          ButtonSegment<Graphendarstellung>(
            value: Graphendarstellung.donut,
            label: Text(AppLocalizations.of(context)!.donutChartShort),
            icon: const Icon(Icons.donut_large),
            padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), // 调整内容边距
          ),
          ButtonSegment<Graphendarstellung>(
            value: Graphendarstellung.saeulen,
            label: Text(AppLocalizations.of(context)!.barChartShort),
            icon: const Icon(Icons.stacked_bar_chart),
            padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
          ),
        ],
        selected: <Graphendarstellung>{_graphendarstellung},
        onSelectionChanged: (Set<Graphendarstellung> newSelection) {
          setState(() {
            _graphendarstellung = newSelection.first;
          });
        },
      ),
    ),
  ],
)

关键调整说明

  • 给SegmentedButton设置padding: EdgeInsets.zero和minimumSize,彻底消除与外层Container的间距
  • 利用BlurStyle.inner属性实现内阴影,这是Flutter中实现内阴影的常用方式
  • 将SegmentedButton背景设为透明,让内层的内阴影效果正常显示
  • 给每个ButtonSegment单独设置padding,保证按钮内容不会过于贴边

内容的提问来源于stack exchange,提问作者Robin.S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 08:35:10