【问题标题】:Flutter BoxShadow overlapping siblingsFlutter BoxShadow 重叠兄弟
【发布时间】:2021-08-05 08:27:37
【问题描述】:

我正在尝试创建一个 Row 的容器,这些容器都具有 BoxShadow。阴影非常大,因此跨越到父级之外的空间,所以我在父级上使用clipBehavior: Clip.none

这样做的问题是,对于行内的每个 Container,它的阴影都会重叠到前一个容器中。我在下面设置了一些粗体颜色来强调这个问题。如您所见,前一个容器的右侧从下一个容器中获取阴影。

这是我的代码

return SingleChildScrollView(
    clipBehavior: Clip.none,
    scrollDirection: Axis.horizontal,
    child: Row(
      children: [
        _ShadowedBox(),
        _ShadowedBox(),
        _ShadowedBox(),
      ],
    ),
  );


class _ShadowedBox extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      width: 144,
      child: Column(
        children: [
          SizedBox(
            width: 144,
            height: 144,
            child: Container(
                decoration: BoxDecoration(
                              color: Colors.grey,
                              shape: BoxShape.rectangle,
                              borderRadius: BorderRadius.circular(cardRadius),
                              boxShadow: [
                                BoxShadow(
                                  offset: const Offset(0.0, 6.0),
                                  blurRadius: 38.0,
                                  spreadRadius: 0.0,
                                  color: Colors.red,
                                ),
                                BoxShadow(
                                  offset: const Offset(0.0, 6.0),
                                  blurRadius: 46.0,
                                  spreadRadius: 0.0,
                                  color: Colors.green,
                                ),
                                BoxShadow(
                                  offset: const Offset(0.0, 6.0),
                                  blurRadius: 10.0,
                                  spreadRadius: 0.0,
                                  color: Colors.blue,
                                ),
                              ]
                          ),
                child: ClipRRect(
                    borderRadius: BorderRadius.circular(cardRadius),
                    child: Image.network("https://via.placeholder.com/400x400.png?text=Coming%20soon", fit: BoxFit.contain)
            ),
          ),
        ],
      ),
    );
  }
}

谁能建议如何阻止阴影渗入其他容器,同时仍然能够显示未被父级剪切的阴影?

【问题讨论】:

  • 重要的clipBehavior: Clip.none实际上是_ShadowedBoxContainer。正如您在实际中看到的那样,当它们同时绘制时,很难将阴影与它们的小部件分开,使其看起来像一个堆栈。你不能使用边距和剪辑行为的组合来在你的元素之间创建空间吗?也许你可以分享一个最终设计?

标签: flutter flutter-layout


【解决方案1】:

好的,我已经测试了 2 种方法来解决您的问题。正如Wapazz 所说,您的每个Container 都是用自己的阴影单独绘制的,因此它们会重叠。

解决方案 #1

一种解决方案可能是将阴影效果应用到您的 Row 小部件而不是 _ShadowedBox,但阴影效果不会那么精确:

代码

SingleChildScrollView(
  clipBehavior: Clip.none,
  scrollDirection: Axis.horizontal,
  child: UnconstrainedBox(
    child: Container(
      decoration: BoxDecoration(
        boxShadow: [
          BoxShadow(
            offset: const Offset(0.0, 6.0),
            blurRadius: 38.0,
            spreadRadius: 0.0,
            color: Colors.red,
          ),
          BoxShadow(
            offset: const Offset(0.0, 6.0),
            blurRadius: 46.0,
            spreadRadius: 0.0,
            color: Colors.green,
          ),
          BoxShadow(
            offset: const Offset(0.0, 6.0),
            blurRadius: 10.0,
            spreadRadius: 0.0,
            color: Colors.blue,
          ),
        ],
      ),
      child: Row(
        children: List<Widget>.generate(10, (_) => _ShadowedBox()),
      ),
    ),
  ),
),

结果

解决方案 #2

我发现的另一个解决方案是使用Stack 小部件,所有阴影都呈现在单独的Row 中,因此生成的阴影具有正确的形状。这种方法的问题是您的小部件需要固定的widthheight

代码

SingleChildScrollView(
  clipBehavior: Clip.none,
  scrollDirection: Axis.horizontal,
  child: Stack(
    children: [
      Row(
        children: List<Widget>.generate(
          10,
          (_) => Container(
            margin: const EdgeInsets.symmetric(horizontal: 4),
            width: 144,
            height: 144,
            decoration: BoxDecoration(
              shape: BoxShape.rectangle,
              borderRadius: BorderRadius.circular(cardRadius),
              boxShadow: [
                BoxShadow(
                  offset: const Offset(0.0, 6.0),
                  blurRadius: 38.0,
                  spreadRadius: 0.0,
                  color: Colors.red,
                ),
                BoxShadow(
                  offset: const Offset(0.0, 6.0),
                  blurRadius: 46.0,
                  spreadRadius: 0.0,
                  color: Colors.green,
                ),
                BoxShadow(
                  offset: const Offset(0.0, 6.0),
                  blurRadius: 10.0,
                  spreadRadius: 0.0,
                  color: Colors.blue,
                ),
              ],
            ),
          ),
        ),
      ),
      Row(
        children: List<Widget>.generate(10, (_) => _ShadowedBox()),
      ),
    ],
  ),
)

结果

You can try my full test code on DartPad

【讨论】:

  • 谢谢,两个很好的解决方案。很遗憾我们的设计师将这种风格放到了许多新屏幕上:D
猜你喜欢
  • 1970-01-01
  • 2021-01-14
  • 2012-08-13
  • 2018-07-24
  • 1970-01-01
  • 2012-08-02
  • 1970-01-01
  • 1970-01-01
  • 2012-05-30
相关资源
最近更新 更多