How to create a circle icon button in Flutter?

In this blog post, we will explore various ways to create a circle icon button in Flutter.

The Old Way: Using RawMaterialButton

In the past, I would have suggested using the `RawMaterialButton` widget. However, as you’ll see later on, it’s not the best option anymore due to its limitations.

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

Why not RawMaterialButton?

While `RawMaterialButton` can be used to create a circle icon button, it has some limitations that make it less desirable. For example, the elevation of the button is fixed at 2.0, and you cannot change it as easily as with other buttons.

The New Way: Using ElevatedButton

With the introduction of `ElevatedButton`, creating a circle icon button has become much simpler. This widget provides more customization options than `RawMaterialButton` and is generally better suited for this purpose.

ElevatedButton with Less Customizations

ElevatedButton(
  onPressed: () {},
  child: Icon(Icons.menu, color: Colors.white),
  style: ElevatedButton.styleFrom(
    shape: CircleBorder(),
    padding: EdgeInsets.all(20),
    backgroundColor: Colors.blue, // <-- Button color
    foregroundColor: Colors.red, // <-- Splash color
  ),
)

ElevatedButton with More Customizations

ElevatedButton(
  onPressed: () {},
  child: Icon(Icons.menu),
  style: ButtonStyle(
    shape: MaterialStateProperty.all(CircleBorder()),
    padding: MaterialStateProperty.all(EdgeInsets.all(20)),
    backgroundColor: MaterialStateProperty.all(Colors.blue), // <-- Button color
    overlayColor: MaterialStateProperty.resolveWith((states) {
      if (states.contains(MaterialState.pressed)) return Colors.red; // <-- Splash color
    }),
  ),
)

Using InkWell

If you prefer not to use the `ElevatedButton` widget, you can create a circle icon button using `InkWell`. This approach requires more code but provides even more customization options.

ClipOval(
  child: Material(
    color: Colors.blue, // Button color
    child: InkWell(
      splashColor: Colors.red, // Splash color
      onTap: () {},
      child: SizedBox(width: 56, height: 56, child: Icon(Icons.menu)),
    ),
  ),
)

Output

The output of the code snippets above will be a circle icon button with the specified properties. The last two examples produce the same result.