Flutter Web PopupMenuButton - can't style The button that open the menu on hover

82 Views Asked by At

I'm tiring for half a day now to change the foregroundColor and remove the backgroundColor of the button on hover, my code:

final ThemeData lightTheme = ThemeData(
  menuButtonTheme: MenuButtonThemeData(style: ButtonStyle(
    foregroundColor: MaterialStateProperty.resolveWith<Color?>(
      (Set<MaterialState> states)  {
        if (states.contains(MaterialState.hovered)) {
          print("this never printed!!!");
          return Colors.red;
        }
        return Colors.blue;
      },
      
    ),
  ))  
);



class AppScreen extends StatelessWidget {
  final Widget? child;
  AppScreen({Key? key, this.child}) : super(key: key);
  
  @override
  Widget build(BuildContext context) {
    
    return Scaffold(
        appBar: AppBar(
          title: Text('AppBar Demo'),
          actions: <Widget>[ 
            PopupMenuButton(
              itemBuilder: (context) => [
                PopupMenuItem<int>(
                  value: 0,
                  child: Text("My Emails"),
                ),
                PopupMenuItem<int>(
                    value: 1, child: Text("Sign Out"),
                ),
              ],
              onSelected: (item) {},
              child: TextButton.icon(
                style: Theme.of(context).menuButtonTheme.style, 
                icon: Icon(Icons.account_circle),
                label: Text(
                  'Maya Amor'
                ), onPressed: null,
              ),       
            )
          ],
        ),
      body: child,
    );
  }
}

The color of the button never change, and when I hover on the button I can see the background of the button changing in a way I can not change, no matter what I did.

1

There are 1 best solutions below

0
On

To change the color of a PopupMenuItem when hovered , you can use the MouseRegion widget

In the onHover and onExit functions, you can implement the logic to change the color

the hover color of a widget is often controlled by the theme of the app. If you want to disable the hover color for a specific widget, you can wrap it in a Theme widget and set the hoverColor to Colors.transparent in the ThemeData

 Theme(
            data: ThemeData(hoverColor: Colors.transparent),
            child: MouseRegion(
              onHover: (event) {
                setState(() {
                  buttonColor = Colors.red; // Change color to red when hovered
                });
              },
              onExit: (event) {
                setState(() {
                  buttonColor = Colors
                      .black; // Change color back to blue when mouse exits
                });
              },
              child: PopupMenuButton(
                itemBuilder: (context) => [
                  PopupMenuItem<int>(
                    value: 0,
                    child: Text("My Emails"),
                  ),
                  PopupMenuItem<int>(
                    value: 1,
                    child: Text("Sign Out"),
                  ),
                ],
                onSelected: (item) {},
                child: TextButton.icon(
                  style: ButtonStyle(
                    foregroundColor: MaterialStateProperty.all(buttonColor),
                  ),
                  icon: Icon(Icons.account_circle),
                  label: Text('Maya Amor'),
                  onPressed: null,
                ),
              ),
            ),
          ),
  

Full Code :

class AppScreen extends StatefulWidget {
  final Widget? child;
  AppScreen({Key? key, this.child}) : super(key: key);

  @override
  _AppScreenState createState() => _AppScreenState();
}

class _AppScreenState extends State<AppScreen> {
  Color buttonColor = Colors.black;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('AppBar Demo'),
        actions: <Widget>[
          Theme(
            data: ThemeData(hoverColor: Colors.transparent),
            child: MouseRegion(
              onHover: (event) {
                setState(() {
                  buttonColor = Colors.red; // Change color to red when hovered
                });
              },
              onExit: (event) {
                setState(() {
                  buttonColor = Colors
                      .black; // Change color back to blue when mouse exits
                });
              },
              child: PopupMenuButton(
                itemBuilder: (context) => [
                  PopupMenuItem<int>(
                    value: 0,
                    child: Text("My Emails"),
                  ),
                  PopupMenuItem<int>(
                    value: 1,
                    child: Text("Sign Out"),
                  ),
                ],
                onSelected: (item) {},
                child: TextButton.icon(
                  style: ButtonStyle(
                    foregroundColor: MaterialStateProperty.all(buttonColor),
                  ),
                  icon: Icon(Icons.account_circle),
                  label: Text('Maya Amor'),
                  onPressed: null,
                ),
              ),
            ),
          ),
        ],
      ),
      body: widget.child,
    );
  }
}

OUTPUT :

enter image description here