How can I add shadow to the widget in flutter?
Asked Answered
G

17

312

How can I add shadow to the widget like in the picture below?

This is my current widget code.

Image with shadow

Gauger answered 7/9, 2018 at 18:22 Comment(3)
take a lookWheatley
you can use stackHux
Wrap your widget with Material() widget and give elevation: 10.0Barrio
C
627

Check out BoxShadow and BoxDecoration

A Container can take a BoxDecoration (going off of the code you had originally posted) which takes a boxShadow

return Container(
  margin: EdgeInsets.only(left: 30, top: 100, right: 30, bottom: 50),
  height: double.infinity,
  width: double.infinity,
  decoration: BoxDecoration(
    color: Colors.white,
    borderRadius: BorderRadius.all(Radius.circular(10)),
    boxShadow: [
      BoxShadow(
        color: Colors.grey.withOpacity(0.5),
        spreadRadius: 5,
        blurRadius: 7,
        offset: Offset(0, 3), // changes position of shadow
      ),
    ],
  ),
)
Carcinoma answered 7/9, 2018 at 18:43 Comment(4)
Great answer - tnx! How would you have the ripple effect over the button? currently it's rippling under the button.Greatcoat
It's better to use borderRadius: BorderRadius.circular(10.0) if every border is same.Augustin
@Greatcoat you can wrap a widget in InkWell widget to get ripple effect on tapping.Promotive
The link you mentioned is not working. Changing the domain from flutter.io to flutter.dev worksPelican
O
150

Screenshot:

enter image description here


  • Using BoxShadow (more customizations):

    Container(
      width: 100,
      height: 100,
      decoration: BoxDecoration(
        color: Colors.teal,
        borderRadius: BorderRadius.circular(20),
        boxShadow: [
          BoxShadow(
            color: Colors.red,
            blurRadius: 4,
            offset: Offset(4, 8), // Shadow position
          ),
        ],
      ),
    )
    
  • Using PhysicalModel:

    PhysicalModel(
      color: Colors.teal,
      elevation: 8,
      shadowColor: Colors.red,
      borderRadius: BorderRadius.circular(20),
      child: SizedBox.square(dimension: 100),
    )
    
  • Using Card:

    Card(
      elevation: 8,
      shadowColor: Colors.red,
      child: Container(
        width: 100,
        height: 100,
        color: Colors.teal,
      ),
    )
    
  • Using Material:

    Material(
      elevation: 8,
      color: Colors.teal,
      shadowColor: Colors.red,
      borderRadius: BorderRadius.circular(20),
      child: SizedBox.square(dimension: 100),
    ) 
    
Ophiology answered 22/10, 2019 at 18:25 Comment(0)
H
121

Use BoxDecoration with BoxShadow.

Here is a visual demo manipulating the following options:

  • opacity
  • x offset
  • y offset
  • blur radius
  • spread radius

The animated gif doesn't do so well with colors. You can try it yourself on a device.

enter image description here

Here is the full code for that demo:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: ShadowDemo(),
      ),
    );
  }
}

class ShadowDemo extends StatefulWidget {
  @override
  _ShadowDemoState createState() => _ShadowDemoState();
}

class _ShadowDemoState extends State<ShadowDemo> {
  var _image = NetworkImage('https://placebear.com/300/300');

  var _opacity = 1.0;
  var _xOffset = 0.0;
  var _yOffset = 0.0;
  var _blurRadius = 0.0;
  var _spreadRadius = 0.0;

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        Center(
          child:
          Container(
            decoration: BoxDecoration(
              color: Color(0xFF0099EE),
              boxShadow: [
                BoxShadow(
                  color: Color.fromRGBO(0, 0, 0, _opacity),
                  offset: Offset(_xOffset, _yOffset),
                  blurRadius: _blurRadius,
                  spreadRadius: _spreadRadius,
                )
              ],
            ),
            child: Image(image:_image, width: 100, height: 100,),
          ),
        ),
        Align(
          alignment: Alignment.bottomCenter,
          child: Padding(
            padding: const EdgeInsets.only(bottom: 80.0),
            child: Column(
              children: <Widget>[
                Spacer(),
                Slider(
                  value: _opacity,
                  min: 0.0,
                  max: 1.0,
                  onChanged: (newValue) =>
                  {
                    setState(() => _opacity = newValue)
                  },
                ),
                Slider(
                  value: _xOffset,
                  min: -100,
                  max: 100,
                  onChanged: (newValue) =>
                  {
                    setState(() => _xOffset = newValue)
                  },
                ),
                Slider(
                  value: _yOffset,
                  min: -100,
                  max: 100,
                  onChanged: (newValue) =>
                  {
                    setState(() => _yOffset = newValue)
                  },
                ),
                Slider(
                  value: _blurRadius,
                  min: 0,
                  max: 100,
                  onChanged: (newValue) =>
                  {
                    setState(() => _blurRadius = newValue)
                  },
                ),
                Slider(
                  value: _spreadRadius,
                  min: 0,
                  max: 100,
                  onChanged: (newValue) =>
                  {
                    setState(() => _spreadRadius = newValue)
                  },
                ),
              ],
            ),
          ),
        )
      ],
    );
  }
}
Honorarium answered 17/1, 2020 at 11:30 Comment(0)
I
17

A Container can take a BoxDecoration (going off of the code you had originally posted) which takes a boxShadow:

decoration: BoxDecoration(
    borderRadius: BorderRadius.circular(10),
    boxShadow: [
        BoxShadow(
            color: Colors.grey.withOpacity(0.5),
            spreadRadius: 5,
            blurRadius: 7,
            offset: Offset(0, 3), // changes position of shadow
        ),
    ],
),
Ideo answered 8/2, 2021 at 12:12 Comment(1)
It seems like I already mentioned these attributes in my post.Ophiology
C
12

PhysicalModel will help you to give it elevation shadow.

 Container(
        alignment: Alignment.center,
        child: Column(
          children: <Widget>[
            SizedBox(
              height: 60,
            ),
            Container(
              child: PhysicalModel(
                borderRadius: BorderRadius.circular(20),
                color: Colors.blue,
                elevation: 18,
                shadowColor: Colors.red,
                child: Container(
                  height: 100,
                  width: 100,
                ),
              ),
            ),
            SizedBox(
              height: 60,
            ),
            Container(
              child: PhysicalShape(
                color: Colors.blue,
                shadowColor: Colors.red,
                elevation: 18,
                clipper: ShapeBorderClipper(shape: CircleBorder()),
                child: Container(
                  height: 150,
                  width: 150,
                ),
              ),
            )
          ],
        ),
      )

enter image description here

Crandale answered 29/1, 2021 at 10:30 Comment(0)
O
11

Use Material with shadowColor inside Container like this:

Container(
  decoration: BoxDecoration(
      borderRadius: BorderRadius.only(
          bottomLeft: Radius.circular(10),
          bottomRight: Radius.circular(10)),
      boxShadow: [
        BoxShadow(
            color: Color(0xffA22447).withOpacity(.05),
            offset: Offset(0, 0),
            blurRadius: 20,
            spreadRadius: 3)
      ]),
  child: Material(
    borderRadius: BorderRadius.only(
        bottomLeft: Radius.circular(10),
        bottomRight: Radius.circular(10)),
    elevation: 5,
    shadowColor: Color(0xffA22447).withOpacity(.05),
    color: Color(0xFFF7F7F7),
    child: SizedBox(
      height: MediaQuery.of(context).size.height / 3,
    ),
  ),
)
Overskirt answered 16/2, 2020 at 18:30 Comment(0)
F
8

this is how I did it

    Container(
  decoration: new BoxDecoration(
    boxShadow: [
      BoxShadow(
        color: Colors.grey[200],
        blurRadius: 2.0, // has the effect of softening the shadow
        spreadRadius: 2.0, // has the effect of extending the shadow
        offset: Offset(
          5.0, // horizontal, move right 10
          5.0, // vertical, move down 10
        ),
      )
    ],
  ),
  child: Container( 
       color: Colors.white, //in your example it's blue, pink etc..
       child: //your content
  )
Formication answered 13/4, 2020 at 17:20 Comment(0)
L
5

The given answers do the trick for outer shadow i.e. around the widget. I wanted a shadow on the widget which is inside the boundaries and according to the github issue there is no inset attribute in ShadowBox yet. My workaround was to add a layer of widget with a gradient using the stack widget so that it looks like the widget itself has the shadows. You must use the mediaQuery for dimensions otherwise the layout will be messed up on different devices. Here's a sample of code for better understanding:

Stack(
            children: <Widget>[
              Container(
                decoration: BoxDecoration(
                  image: DecorationImage(
                    fit: BoxFit.cover,
                    image: AssetImage("assets/sampleFaces/makeup.jpeg"),
                    // fit: BoxFit.cover,
                  ),
                ),
                height: 350.0,
              ),
              Container(
                decoration: BoxDecoration(
                  gradient: LinearGradient(
                    begin: FractionalOffset.topCenter,
                    end: FractionalOffset.bottomCenter,
                    colors: [
                      Colors.black.withOpacity(0.0),
                      Colors.black54,
                    ],
                    stops: [0.95, 5.0],
                  ),
                ),
              )
            ],
          ),
Labroid answered 26/11, 2019 at 20:46 Comment(0)
B
5

Before you start reinventing the wheel with one of these answers, check out the Material Card widget. It also allows you to define a global style via the app theme directly:

example

Beni answered 16/2, 2021 at 2:52 Comment(0)
P
4
class ShadowContainer extends StatelessWidget {
  ShadowContainer({
    Key key,
    this.margin = const EdgeInsets.fromLTRB(0, 10, 0, 8),
    this.padding = const EdgeInsets.symmetric(horizontal: 8),
    this.circular = 4,
    this.shadowColor = const Color.fromARGB(
        128, 158, 158, 158), //Colors.grey.withOpacity(0.5),
    this.backgroundColor = Colors.white,
    this.spreadRadius = 1,
    this.blurRadius = 3,
    this.offset = const Offset(0, 1),
    @required this.child,
  }) : super(key: key);

  final Widget child;
  final EdgeInsetsGeometry margin;
  final EdgeInsetsGeometry padding;
  final double circular;
  final Color shadowColor;
  final double spreadRadius;
  final double blurRadius;
  final Offset offset;
  final Color backgroundColor;

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: margin,
      padding: padding,
      decoration: BoxDecoration(
        color: backgroundColor,
        borderRadius: BorderRadius.circular(circular),
        boxShadow: [
          BoxShadow(
            color: shadowColor,
            spreadRadius: spreadRadius,
            blurRadius: blurRadius,
            offset: offset,
          ),
        ],
      ),
      child: child,
    );
  }
}
Pisarik answered 10/11, 2020 at 4:16 Comment(0)
N
4

Maybe it is sufficient if you wrap a Card around the Widget and play a bit with the elevation prop.

I use this trick to make my ListTile look nicer in Lists.

For your code it could look like this:

return Card(
   elevation: 3, // PLAY WITH THIS VALUE 
   child: Row(
      crossAxisAlignment: CrossAxisAlignment.center,
      children: <Widget>[
         // ... MORE OF YOUR CODE 
      ],
   ),
);
Neologize answered 6/2, 2021 at 5:49 Comment(0)
G
3

To add shadow to an any widget in flutter, You can just wrap that widget with Container and set following properties:

Container(
  decoration: BoxDecoration(
    boxShadow: [
      BoxShadow(
        color: Colors.grey.withOpacity(0.5),
        spreadRadius: 2,
        blurRadius: 5,
        offset: Offset(0, 3),
      ),
    ],
  ),
  child: YourWidget(), // Replace YourWidget with your desired widget
);

Happy Fluttering!

Gastelum answered 16/5, 2023 at 5:30 Comment(2)
This causes the entire container to be covered with 50% gray, it's not the right solution.Fairchild
You can manage shadow with given properties. @LukeHutchison Thanks thoughGastelum
M
1

If you are using the Material Design spec inside Flutter, you can use a helper kElevationToShadow to create shadows that match the elevation property used in other Material components.

You can see the documentation for this property here: https://api.flutter.dev/flutter/material/kElevationToShadow-constant.html

The following elevations have defined shadows: 1, 2, 3, 4, 6, 8, 9, 12, 16, 24

Example with a Container:

Container(
  decoration: BoxDecoration(
    color: Colors.white,
    boxShadow: kElevationToShadow[8],
  ),
)

This is an easy way to add shadows that match the Material specifications, the bigger the elevation the deeper the shadow, so you can play with this value until it fits your purpose.

Mettah answered 20/9, 2023 at 0:28 Comment(0)
L
0
Container(
  width: 100,
  height: 100,
  decoration: BoxDecoration(
    color: Colors.purple,
    borderRadius: BorderRadius.circular(20),
    boxShadow: [
      BoxShadow(
        color:  Colors.purple.withOpacity(0.3),
        blurRadius: 4,
        offset: Offset(6, 5), // Shadow position
      ),
    ],
  ),
),
Lustrate answered 15/7, 2023 at 9:36 Comment(0)
S
0

try this

Container(
                        width: double.infinity,
                        decoration: BoxDecoration(
                          gradient: RadialGradient(
                            center: AlignmentDirectional.topEnd,
                            focalRadius: 5,
                            focal: AlignmentDirectional.topEnd,
                            colors: [
                              Themes.primaryColorDark.withOpacity(0.5),
                              Themes.primaryColorDark.withOpacity(0.2),
                            ],
                            stops: [0.9, 0.0],
                          ),
                          borderRadius: BorderRadius.circular(25.0),
                        ),
Shapely answered 29/7, 2023 at 21:9 Comment(0)
C
0
Container(
          decoration: BoxDecoration(
            color: MyColors.whiteColor,
            borderRadius: BorderRadius.circular(6),
            boxShadow: const [
              BoxShadow(
                offset: Offset(0, 2),
                blurRadius: 40,
                color: Colors.blue.secondary,
              ),
            ],
          ),
          child....

)

Causeuse answered 2/2 at 15:20 Comment(1)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Quatrain
C
-2

Wrap your widget into container and give box shadow list to it

Carlyn answered 26/1, 2022 at 13:29 Comment(2)
This does not provide an answer to the question. Once you have sufficient reputation you will be able to comment on any post; instead, provide answers that don't require clarification from the asker. - From ReviewHag
Correct, but too vague. Add the code, so that people can basically just copy it into their own code and it'll work! From there, they can personalize it as they want. See below upvoted answer for an excellent example.Giustino

© 2022 - 2024 — McMap. All rights reserved.