22

I'm trying to make a widget that renders one of the circles shown in this image. It is a transparent circle with a box-shadow. The circle should show whichever color or background image that is applied to the parent container. The circle is transparent but what I see is this: a black box shadow and not the background color of the parent. Any suggestions?

Here is what I have so far:

class TransParentCircle extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
        child: new Center(
          child: new Container(
            decoration: new BoxDecoration(
              border: new Border.all(width: 1.0, color: Colors.black),
              shape: BoxShape.circle,
              color: Colors.transparent,
              boxShadow: <BoxShadow>[
                BoxShadow(
                  color: Colors.black,
                  offset: Offset(1.0, 6.0),
                  blurRadius: 40.0,
                ),
              ],
            ),
            padding: EdgeInsets.all(16.0),
          ),
        ),
        width: 320.0,
        height: 240.0,
        margin: EdgeInsets.only(bottom: 16.0));
  }
}
bec
  • 223
  • 1
  • 2
  • 4

4 Answers4

49

As you can see in the BoxShadow class, they subclass the toPaint() method like this :

Paint toPaint() {
  final Paint result = Paint()
    ..color = color
    ..maskFilter = MaskFilter.blur(BlurStyle.normal, blurSigma);
  assert(() {
    if (debugDisableShadows)
      result.maskFilter = null;
    return true;
  }());
  return result;
}

... with BlurStyle.normal instead of BlurStyle.outer as we wanted.

Let's just create a custom BoxShadow that takes the BlurStyle as parameter.

import 'package:flutter/material.dart';

class CustomBoxShadow extends BoxShadow {
  final BlurStyle blurStyle;

  const CustomBoxShadow({
    Color color = const Color(0xFF000000),
    Offset offset = Offset.zero,
    double blurRadius = 0.0,
    this.blurStyle = BlurStyle.normal,
  }) : super(color: color, offset: offset, blurRadius: blurRadius);

  @override
  Paint toPaint() {
    final Paint result = Paint()
      ..color = color
      ..maskFilter = MaskFilter.blur(this.blurStyle, blurSigma);
    assert(() {
      if (debugDisableShadows)
        result.maskFilter = null;
      return true;
    }());
    return result;
  }
}

Now we can use it like this :

new CustomBoxShadow(
  color: Colors.black,
  offset: new Offset(5.0, 5.0),
  blurRadius: 5.0,
  blurStyle: BlurStyle.outer
)
mastohhh
  • 561
  • 6
  • 5
  • Thank you very much, this helped me a lot!! – Reiko Dev May 25 '21 at 18:33
  • 3
    Even though this is an accepted answer it shouldn't be any more. native `BoxShadow` now allows to customize `blurStyle` so you don't have to create custom class. – bakua Feb 24 '22 at 11:24
  • This indeed works in creating a shadow as long as your child widget is not transparent, in which case it always shows an entire box. – CoastalB Jul 13 '23 at 16:57
5
Container(
height: 200.0,
decoration: BoxDecoration(
    boxShadow: [
      BoxShadow(
        color: Colors.black,
        blurRadius: 10.0, // soften the shadow
        spreadRadius: 7.0, //extend the shadow
        offset: Offset(
          5.0, // Move to right 10  horizontally
          5.0, // Move to bottom 5 Vertically
        ),
      )
    ],
),
child: Text(" ", style:TextStyle(fontSize:30)),

);

Seddiq Sorush
  • 2,709
  • 2
  • 20
  • 20
0

This is working for everyone

  Container(
    height: 210.0,
    decoration: BoxDecoration(
        boxShadow: [
          new BoxShadow(
            color: Colors.grey,
            blurRadius: 10.0,
          ),],

    ),
  child: ClipPath(
    clipper: ShapeBorderClipper(
        shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.all(Radius.circular(10))
        )
    ),
    child: Container(
      height: 200.0,
        decoration: BoxDecoration(
            color: Colors.white,
            border: Border(
                left: BorderSide(
                    color: Theme.of(context).primaryColor,
                    width: 7.0
                )
            )
        ),
      child: Text("kokoko"),
    ),
  ),
);
Mahesh Gv
  • 11
  • 4
-1
Container(
  height: 380,
  decoration: BoxDecoration(
    borderRadius: BorderRadius.circular(20),
    boxShadow: [
      CustomBoxShadow(
          color: Colors.black.withOpacity(0.25),
          blurRadius: 5,
          blurStyle: BlurStyle.outer
          ),
    ],
  ),
  child: Container(
    decoration: BoxDecoration(
      color: Colors.white,
      borderRadius: BorderRadius.circular(20),
    ),
    child: Container(
      decoration: BoxDecoration(
        color : Colors.white.withOpacity(.25),
        borderRadius: BorderRadius.circular(20),
      ),
    ),
  ),

On ios there were black box behind of my transparent gradient widget. I think it uses that box to render the shadow. So, I had to add extra layer to container to ovverride that box. Result is this

Alper
  • 1