How to set a custom elevation color on Flutter?

28,051

Solution 1

Since FlatButton, RaisedButton, and OutlineButton are now deprecated I thought of adding an easier up to date way. The accepted answer therefore is not entirely correct anymore since the Material Design principles the answer refers to changed.

See (source):

FlatButton, RaisedButton, and OutlineButton have been replaced by TextButton, ElevatedButton, and OutlinedButton respectively.

TextButton(
        style: ButtonStyle(
          backgroundColor: MaterialStateProperty.all(color), //Background Color
          elevation: MaterialStateProperty.all(3), //Defines Elevation
          shadowColor: MaterialStateProperty.all(color), //Defines shadowColor
        ),
        onPressed: () {},
        child: Text('bla'),
        ),
)

This is also applicable for ElevatedButton and OutlinedButton.

Solution 2

Edit: After 2 years of updates, things are changed. For the updates check the answer: https://stackoverflow.com/a/66638462/10380182

It is not possible to change default elevation color right now in Flutter. And in my opinion, it won't be, because of Material Design principles.

Create a wrapper Container then wrap your Button Widget(that has no elevation) with the Container.

You can tweak the BoxShadow however you want. Also you can add additional elevation to right and left side with half strength Offset(1, 0) & Offset(-1, 0).

Container(for blue color e.g.):

class CustomElevation extends StatelessWidget {
  final Widget child;

  CustomElevation({@required this.child}) : assert(child != null);

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: BoxDecoration(
        boxShadow: <BoxShadow>[
          BoxShadow(
            color: Colors.blue.withOpacity(0.1),
            blurRadius: 1,
            offset: Offset(0, 2),
          ),
        ],
      ),
      child: this.child,
    );
  }
}

Usecase:

CustomElevation(
  child: FlatButton(
    color: Colors.blue,
    onPressed: () {},
    child: Text('Custom Elevation'),
  ),
)

Edit: For StadiumBorder buttons:

We create height parameter for the Container:

class CustomElevation extends StatelessWidget {
  final Widget child;
  final double height;

  CustomElevation({@required this.child, @required this.height})
      : assert(child != null);

  @override
  Widget build(BuildContext context) {
    return Container(
      height: this.height,
      decoration: BoxDecoration(
        borderRadius: BorderRadius.all(Radius.circular(this.height / 2)),
        boxShadow: <BoxShadow>[
          BoxShadow(
            color: Colors.blue.withOpacity(0.2),
            blurRadius: height / 5,
            offset: Offset(0, height / 5),
          ),
        ],
      ),
      child: this.child,
    );
  }
}

then:

CustomElevation(
  height: 60,
  child: FlatButton(
    shape: StadiumBorder(),
    color: Colors.blue,
    onPressed: () {},
    child: Text('Custom Elevation'),
  ),
)
Share:
28,051
Jehad Nasser
Author by

Jehad Nasser

My Blogs: How to configure Gitlab-CI to Auto-deploy your App via SSH Data-binding in Flutter or passing data from a child widget to a parent widget Understanding how Equatable works

Updated on July 09, 2022

Comments

  • Jehad Nasser
    Jehad Nasser almost 2 years

    I am trying to customize the color of the RaisedButton's shadow on flutter, e.g Green instead of Grey, I don't want to put the button inside a Container like all solutions on the internet, so I hope that there's a solution using elevation and the old answer that this is not possible by "android material" is not an issue any more.

    Edited: the problem with the container with ShadowBox solution is that will be Spread to all sides as the offset has two values only,vertical and horizontal, and if we push the ShadowBox to make it in one side only, then in one side BUT it's going to be big(half of the button height)!

    So if there's a way to make the child(RaisedButton) bigger than the container then that would be a solution.

    I am trying to use Stack(..Positioned(..)) but no luck so far.

    BTW, this is the button that I need a native but colorful shadow for it.

    RaisedButton(
       padding: EdgeInsets.symmetric(vertical: 15.0),
       shape: RoundedRectangleBorder(
             borderRadius: BorderRadius.circular(30.0)
       ),
       color: Theme.of(context).primaryColor,
       onPressed: () => print('Hello'),
       child: Center(Text(...)),
    ),  
    

    I want a shadow at the bottom only with same color as the button: button with same color shadow

    but what I am getting so far:

    buttons with diff shadows

    thanks

  • Jehad Nasser
    Jehad Nasser almost 5 years
    Thank you for the answer, really appreciate it. But the problem is with the shape of my button, as its radius is 30.0, please have a look here: imgur.com/Hy6Alxo
  • Esen Mehmet
    Esen Mehmet almost 5 years
    @JehadNasser I edited the answer towards to your need.
  • Jehad Nasser
    Jehad Nasser almost 5 years
    Just what I am looking for, works like a charm! Thank you so much ))
  • nhp
    nhp about 2 years
    exactly what i'm looking for, thanks a lot, worked like a charm!
  • KhoPhi
    KhoPhi almost 2 years
    In Flutter 3, no need for the MaterialStateProperty. Just elevation: x.x should be fine. Thanks for the answer