androidfluttermaterial-designflutter-layout

How to set a custom elevation color on Flutter?


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


Solution

  • 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'),
      ),
    )