67

I want to apply background color for icon button but I don't see an explicit backgroundColor property for it. I want to achieve this:

enter image description here

Currently I was able to achieve till here:

enter image description here

Below is the code so far:

@override
  Widget build(BuildContext context) {

return Scaffold(
    resizeToAvoidBottomPadding: false,
    backgroundColor: Color(0xFF13212C),
    appBar: AppBar(
      title: Text('Demo'),
    ),
    drawer: appDrawer(),
    body: new Center(
    child: new Column(
    crossAxisAlignment: CrossAxisAlignment.stretch,
 //     mainAxisAlignment: MainAxisAlignment.spaceEvenly,
    children: <Widget>[
      new Column(
        children: <Widget>[
       //   new Flexible(
    new TextField(
        style: new TextStyle(
        color: Colors.white,
      fontSize: 16.0),
      cursorColor: Colors.green,
      decoration: new InputDecoration(

        suffixIcon: new IconButton(
            icon: new Image.asset('assets/search_icon_ivory.png'),onPressed: null),

      fillColor: Colors.black,
        contentPadding: new EdgeInsets.fromLTRB(10.0, 20.0, 10.0, 20.0),
        filled: true,
        hintText: 'What Do You Need Help With?',
        hintStyle: new TextStyle(
          color: Colors.white
        )
    )
    )
      //    )
    ]
),
Darshan Kunjadiya
  • 3,323
  • 1
  • 29
  • 31
Darshan
  • 10,550
  • 5
  • 49
  • 61

18 Answers18

80

You can use a Circular Avatar with the radius = text field's height/2 or whatever height you prefer.

To figure out text field specs you can visit material.io

So the chunk of code is going to be like the following:

CircleAvatar(
                radius: 30,
                backgroundColor: Color(0xff94d500),
                child: IconButton(
                  icon: Icon(
                    Icons.search,
                    color: Colors.black,
                  ),
                  onPressed: () {
                    ...
                  },
                ),
              ),

This way you get an Icon button with background color. I hope this can help you guys.

Icon button with background

FJCG
  • 1,017
  • 7
  • 6
55

you can wrap your IconButton with Container and use color property to achieve desire output. May Following Example help You.

 suffixIcon: Container(
              color: Colors.green,
              child: new IconButton(
                  icon: new Icon(Icons.search,color: Colors.white,),onPressed: null),
            ),
Viren V Varasadiya
  • 25,492
  • 9
  • 45
  • 61
  • 1
    with this implementation you'll have a little bit weird animation when `onPressed` will be not `null`. but still will work. – olexa.le Oct 12 '18 at 10:44
  • Flutter has a lot of icons, always try to find the icon you want before to use an external one – dmarquina Oct 12 '18 at 21:22
  • 2
    You also don't get all the awesome built-in flutter ink / splash effects when using a plain container. Check out [the flutter docs for IconButton](https://api.flutter.dev/flutter/material/IconButton-class.html), it has been updated to include an example of how to set background color while retaining these nice details by using an `Ink` widget – James Allen Nov 09 '21 at 17:23
  • James Allen's comment is the best answer! – Ashkan Sarlak Apr 07 '22 at 22:47
30

From the official Flutter docs:

Adding a filled background

Icon buttons don't support specifying a background color or other background decoration because typically the icon is just displayed on top of the parent widget's background. Icon buttons that appear in AppBar.actions are an example of this.

It's easy enough to create an icon button with a filled background using the Ink widget. The Ink widget renders a decoration on the underlying Material along with the splash and highlight InkResponse contributed by descendant widgets.

Tl;dr: IconButton doesn't support background color out-of-the-box. Use this workaround to add the background color and the splash effect when clicking the button:

Ink(
  decoration: ShapeDecoration(
    color: Colors.blue,
    shape: CircleBorder(),
  ),
  child: IconButton(
    icon: Icon(Icons.add),
    color: Colors.white,
    onPressed: () {},
  ),
),

Live Demo

This is now the officially recommended way to set background color on an IconButton, and the flutter docs have been updated to reflect this.

ruleboy21
  • 5,510
  • 4
  • 17
  • 34
NearHuscarl
  • 66,950
  • 18
  • 261
  • 230
  • 4
    This is now the officially recommended way to set background color on an IconButton, and the [flutter docs have been updated to reflect this](https://api.flutter.dev/flutter/material/IconButton-class.html). This should be the top answer. – James Allen Nov 09 '21 at 17:19
  • This works for blue - but if I change the colour to white, which is what I need, then it instead does nothing. – kris Jul 13 '22 at 19:12
  • 1
    when i use this solution inside stack the backgroundColor doesn't show up, what is the problem here, do you think? – Duck Programmer Dec 29 '22 at 10:55
  • @DuckProgrammer Same here. Did you find a solution? I have to use CircleAvatar at this stage. – BeniaminoBaggins Mar 13 '23 at 06:33
25

You can achieve it with TextButton

    TextButton(
      style: TextButton.styleFrom(
        backgroundColor: colorScheme.primary,
        shape: CircleBorder(),
      ),
      child: Icon(
        MdiIcons.send,
        color: colorScheme.onPrimary,
      ),
      onPressed: () {},
    ),

The output will look like this: enter image description here

ulusoyca
  • 841
  • 9
  • 18
10

Hope, this will satisfied you

Ink(
  decoration: ShapeDecoration(
     color: Colors.red,
     shape: CircleBorder(),
  ),
  child: IconButton(
    icon: Icon(Icons.delivery_dining),
    onPressed: () {
    print('pressed');
    },
  ),
),
Mukta
  • 1,357
  • 1
  • 15
  • 17
10

With latest flutter and material-3 design system, this is just a piece a cake.

IconButton(
  onPressed: () { ... },
  icon: const Icon(Icons.search),
  style: IconButton.styleFrom(backgroundColor: Colors.redAccent),
),
7

You can not do that with IconButton widget yet. Good news is that you may replace it with FlatButton like that:

suffixIcon: new FlatButton(
                      color: Colors.green,
                      disabledColor: Colors.green[100],
                      child: Icon(Icons.search)),

color will be used in case onPressed handler is defined, otherwise it will be rendered with disabledColor background.

olexa.le
  • 1,697
  • 10
  • 14
3

IconButton does not support that, and RaisedButton recently is deprecated in favour of ElevatedButton, which supports changing background colours as well as shapes, but you cannot easily make it a perfect circle.

So to think out of the box, why not use a FloatingActionButton? They are just widgets too, so they can appear anywhere on the screen. For example, I'm using a FAB in a video chat demo app to toggle cameras.

Use a FAB at a random location on the screen

Example code:

FloatingActionButton(
  child: Icon(
    Icons.flip_camera_ios_outlined,
    color: Colors.white,
  ),
  onPressed: () {
    // do your thing here
  },
)

And if you aren't happy about its default size, you can always wrap it with a SizedBox to change the width however you see fit.

WSBT
  • 33,033
  • 18
  • 128
  • 133
1

Add a Material

Material(
color:Colors.green
child:IconButton(
    icon: Icon(Icons.add),
    color: Colors.white,
    onPressed: () {},
  ));
Dean Villamia
  • 576
  • 11
  • 24
1

I've used multiple colors to demonstrate You can do as you want. And I say that You put your IconButton into Material widget. This will also solve your Splash Color (which is slightly grey color with some transparency).

enter image description here

General Grievance
  • 4,555
  • 31
  • 31
  • 45
Hammad Pervez
  • 316
  • 4
  • 12
1

Official solution:

Depends on official documentation of flutter about IconButton Class:

Adding a filled background

Icon buttons don't support specifying a background color or other background decoration because typically the icon is just displayed on top of the parent widget's background. Icon buttons that appear in [AppBar.actions] are an example of this.

It's easy enough to create an icon button with a filled background using the [Ink] widget. The [Ink] widget renders a decoration on the underlying [Material] along with the splash and highlight [InkResponse] contributed by descendant widgets.

So the code will be like this:

   Material(
    color: Colors.transparent,
    child: Ink(
      decoration: ShapeDecoration(
        color: Colors.white,
        shape: CircleBorder(),
      ),
      child: IconButton(
        tooltip: "Some Text...",
        icon: Icon(Icons.flash_off),
        color: Colors.black,
        onPressed: () {},
      ),
    ),
  );

See official example code from flutter, click here ...

Note: Reason to wrap it with Material widget because Ink is drawn on the underlying Material widget, if you remove it decoration will not appear.

AnasSafi
  • 5,353
  • 1
  • 35
  • 38
1
SizedBox(
  height: 38,
  width: 38,
  child: ElevatedButton(
    style: ElevatedButton.styleFrom(
    primary: Colors.grey,
    onPrimary: Colors.red,
    padding: EdgeInsets.zero,
    shape: const CircleBorder(),
  ),
  onPressed: () {},
  child: const Icon(Icons.refresh),
);
Eng
  • 1,617
  • 2
  • 12
  • 25
1

You can solve this with a GestureDetector and a container. I like using this solution because of the variety of controls it gives you from the combination.

Additionally, GestureDetector opens up more interaction events if you want to incorporate those across devices.

GestureDetector(
      onTap: () {},
      child: ClipOval(
        child: Container(
          //add extra margin to visual center icon if icon isn't balanced
          color: backgroundColor,
          width: size,
          height: size,
          child: Icon(
            Icons.question_mark_sharp,
            size: size * 0.6, //size to your preference
            color: iconColor,
          ),
        ),
      ),
    );

Alternatively you can do this from another question circle icon button

RawMaterialButton(
  onPressed: () {},
  elevation: 2.0,
  fillColor: Colors.white,
  child: Icon(
    Icons.pause,
    size: 35.0,
  ),
  padding: EdgeInsets.all(15.0),
  shape: CircleBorder(),
)

1

If you're using Material 3, Flutter has introduced IconButton.filled() constructor which gives it a background color automatically based on the material colorScheme. It also has the added benefit of adjusting to different icon sizes.

Example:

IconButton.filled(
    icon: const Icon(Icons.phone)
)

dark mode filled IconButton light mode filled IconButton
Dark mode and light mode filled IconButtons

If you want to specify a color, use this answer

FGoo
  • 93
  • 1
  • 5
1
suffixIcon: Container(
decoration: BoxDecoration(
  color: Colors.blue, 
  borderRadius: BorderRadius.circular(8), 
),
child: IconButton(
  icon: Icon(Icons.add),
  onPressed: () {
  },
  color: Colors.white, 
),

),

0

If you want it raised, you can use RaisedButton like this:

                          ConstrainedBox(
                            constraints: BoxConstraints(maxWidth: 50),
                            child: RaisedButton(
                              color: kColorLightGrey,
                              padding: EdgeInsets.symmetric(
                                vertical: 12,
                              ),
                              shape: StadiumBorder(),
                              child: Icon(Icons.refresh),
                              onPressed: () {
                              },
                            ),
                          ),
Daniel Vilela
  • 587
  • 1
  • 4
  • 19
0

You can use FloatingActionButton for such case But you cannot use FAB in a widget for multi use, it shows error. In such case use this code. It will work on images also.

  Card(
    color: Colors.blue,
    shape: CircleBorder(), 
    child: IconButton(
        icon: const Icon(
          Icons.edit,
          size: 20,
          color: Colors.white,
        ),
        onPressed: () {
          print('tapped');  
        },
      ));
R.Raman
  • 64
  • 5
-1

ElevatedButton with Theme.

 ElevatedButton(
  style: ButtonThemes.iconButton,
  child: Icon(
    icon,
    color: color,
  ),
  onPressed: () {},
)
static ButtonStyle get iconButton=> ButtonStyle(
  backgroundColor: MaterialStateProperty.all(
    backgroundColor,
  ),
  ...
);