Matt R
Matt R

Reputation: 10533

Correct ripple effect shape for circular icon popup menu

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?

Upvotes: 2

Views: 3269

Answers (1)

Ovidiu
Ovidiu

Reputation: 8714

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.

Upvotes: 15

Related Questions