2

In Flutter, I'm wanting to style icon buttons with a circular border, and also have the Material ripple effect work correctly so that the ripple effect is contained with the circle. In the following code, the first button works correctly. In the second (popup) button, the ripple effect extends out to a square that surrounds the button, rather than being constrained to the circular border.

The second button

MaterialApp(
  home: Scaffold(
    body: Center(
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          Container(
            decoration: BoxDecoration(
              border: Border.all(color: Colors.black, width: 2),
              shape: BoxShape.circle,
            ),
            child: MaterialButton(
              minWidth: 0,
              padding: EdgeInsets.all(0.0),
              child: Padding(
                padding: EdgeInsets.all(11.0),
                child: Icon(Icons.home, size: 27.0),
              ),
              shape: CircleBorder(),
              onPressed: () {},
            ),
          ),
          PopupMenuButton<String>(
            onSelected: (String action) {},
            child: Container(
              decoration: BoxDecoration(
                border: Border.all(color: Colors.black, width: 2),
                shape: BoxShape.circle,
              ),
              child: Padding(
                padding: EdgeInsets.all(11.0),
                child: Icon(Icons.menu, size: 27.0),
              ),
            ),
            itemBuilder: (BuildContext context) => [
              PopupMenuItem<String>(child: ListTile(title: Text('Log Out'))),
            ],
          ),
        ],
      ),
    ),
  ),
);

Is there a way to get the popup button working correctly?

Matt R
  • 9,892
  • 10
  • 50
  • 83
  • Have you tried wrapping your `PopupMenuButton` with a `ClipRRect`? – Ovidiu Oct 21 '19 at 10:34
  • @Ovidiu I tried `ClipRRect(borderRadius: BorderRadius.circular(24), child: PopupMenuButton(...))`, but it unfortunately didn't have any effect. – Matt R Oct 21 '19 at 11:01

1 Answers1

14

You need to use ClipRRect as well as Material:

ClipRRect(
  borderRadius: BorderRadius.circular(24),
  child: Material(
    color: Colors.transparent,
    child: PopupMenuButton<String>(
    ...

PopupMenuButton wraps the child with an InkWell, which for some reason is not clipped unless also wrapped within Material.

Ovidiu
  • 8,204
  • 34
  • 45