Flutter:如何为透明容器添加阴影?

Flutter: How to add shadow to transparent container?

我只想在透明容器的边缘有一个阴影,如您在顶部导航栏中看到的那样 [图 1]。 Boxshadow 在这种情况下不起作用,因为您会看到透明小部件后面的整个阴影。有没有办法只从边缘添加阴影?

感谢您的帮助

作为解决方法,您可以将容器的颜色设置为其背景颜色。然后就可以使用BoxShadow了。

我想弄清楚如何使用裁剪器裁剪容器内部以去除阴影颜色。

这是我的解决方案

首先,我创建了一个 InvertedClipper 其任务是剪辑小部件的内部:

class InvertedClipper extends CustomClipper<Path> {


InvertedClipper();

  @override
  Path getClip(Size size) {
    return Path.combine(
      PathOperation.difference,
      Path()..addRect(Rect.fromLTWH(0, 0, size.width, size.height)),
      Path()..addRect(Rect.fromLTWH(1, 1, size.width - 5, size.height - 5)),
    );
  }

  @override
  bool shouldReclip(CustomClipper<Path> oldClipper) => true;
}

为此,我关注了 this interesting article

就是说,我立即尝试了裁剪器,但注意到如果用阴影裁剪 Container,阴影会丢失 spreadblur

谷歌搜索我偶然发现了包 clip_shadow,它允许向剪辑的小部件添加阴影(这正是您所需要的)。

根据自述文件,我这样做了:

class DummyHome extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.blue,
      body: Center(
        child: ClipShadow(
          boxShadow: [
            BoxShadow(
              color: Colors.black,
              spreadRadius: 5,
              blurRadius: 7,
              offset: Offset(0, 3), // changes position of shadow
            ),
          ],
          clipper: InvertedClipper(),
          child: Container(
            height: 250,
            width: 250,
            color: Colors.transparent,
          ),
        ),
      ),
    );
  }
}

这导致了这个结果:

对不起,图片太大了,我不知道如何在 Markdown 中调整它的大小。除此之外,我希望这对您有所帮助。

编码愉快!

试试这个自定义 Decoration(如果需要,您可以添加一些其他参数,如背景颜色、渐变等):

class FooDecoration extends Decoration {
  final EdgeInsets insets;
  final Color color;
  final double blurRadius;
  final bool inner;

  FooDecoration({
    this.insets = const EdgeInsets.all(12) ,
    this.color = Colors.black,
    this.blurRadius = 8,
    this.inner = false,
  });
  @override
  BoxPainter createBoxPainter([void Function() onChanged]) => _FooBoxPainter(insets, color, blurRadius, inner);
}

class _FooBoxPainter extends BoxPainter {
  final EdgeInsets insets;
  final Color color;
  final double blurRadius;
  final bool inner;

  _FooBoxPainter(this.insets, this.color, this.blurRadius, this.inner);

  @override
  void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
    var rect = offset & configuration.size;
    canvas.clipRect(rect);
    var paint = Paint()
      ..color = color
      ..maskFilter = MaskFilter.blur(BlurStyle.outer, blurRadius);

    var path = Path();
    if (inner) {
      path
        ..fillType = PathFillType.evenOdd
        ..addRect(insets.inflateRect(rect))
        ..addRect(rect);
    } else {
      path.addRect(insets.deflateRect(rect));
    }
    canvas.drawPath(path, paint);
  }
}

示例用法(注意所有参数都有一些默认值):

child: Container(
  color: Colors.grey[200],
  child: Container(
    decoration: FooDecoration(
      insets: EdgeInsets.only(top: 15, bottom: 15),
      // color: Colors.black,
      // blurRadius: 8,
      // inner: true,
    ),
  ),
),