Home > Back-end >  How to wrap a PopupMenuItem in a seperate file?
How to wrap a PopupMenuItem in a seperate file?

Time:09-21

I would like to wrap a PopupMenuItem in a seperate file, because I am going to need a lot of them. I fail to do so because the itemBuilder in the PopupMenuButton excpects something I cannot fulfill.

This i where I want to use the wrapped item:

PopupMenuButton<String>(
    itemBuilder: (context) => [MyWrappedMenuItem(title: 'title')],
)

And this is the wrapped PopupMenuItem component file:

class MyWrappedMenuItem extends StatelessWidget {
  final String title;
  final String? value;
  final IconData? icon;
  final void Function()? onTap;
  const MyWrappedMenuItem({Key? key, required this.title, this.value, this.icon, this.onTap}) : super(key: key);

  @override
  PopupMenuEntry<String> build(BuildContext context) {
    return PopupMenuItem(
      value: value,
      child: ListTile(
        onTap: onTap,
        minLeadingWidth: 1,
        contentPadding: EdgeInsets.only(left: 0),
        title: Text(title, style: Theme.of(context).textTheme.subtitle1),
        leading: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Icon(
              icon,
              size: 16,
            ),
          ],
        ),
      ),
    );
  }
}

I´ve tried playing around with some typecasting, but none of it seems to work. I get this error:

_CastError (type 'MyWrappedMenuItem' is not a subtype of type 'PopupMenuEntry' in type cast)

So what is wrong, and how do you properly wrap this item, or another flutter UI component item for that matter?

CodePudding user response:

it expects a PopupMenuItem but by wrapping it in a StatelessWidget it's no longer that so you can't use that. The solution is to make a new function that returns it instead. So something like this:

PopupMenuEntry<String> myWrappedMenuItem (BuildContext context, {required String title, String? value, IconData? icon, void Function()? onTap}) {
  return PopupMenuItem(
    value: value,
    child: ListTile(
      onTap: onTap,
      minLeadingWidth: 1,
      contentPadding: EdgeInsets.only(left: 0),
      title: Text(title, style: Theme.of(context).textTheme.subtitle1),
      leading: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          Icon(
            icon,
            size: 16,
          ),
        ],
      ),
    ),
  );
}
  • Related