Home > Net >  How to pass Navigator or Void function as a parameter to a ListTile Widget -Flutter
How to pass Navigator or Void function as a parameter to a ListTile Widget -Flutter

Time:05-18

I'm Calling the Widget from my Home Page, and sending the required data as argument. like this:

     AppDrawerListTile(
                      title: 'Logout',     // title of the List Tile.
                      icon: Icons.logout, // icon for the list tile.
                      action: () {       // onTap action for ListTile - which is not working
                        Navigator.push(context, MaterialPageRoute(builder: (context) => LoginPage()));
                      }),

And here is the Custom Common List where, I'm getting the parameters and providing it to the ListTile.

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

  @override
  Widget build(BuildContext context) {
    return ListTile(
      minVerticalPadding: 0,
      title: title.text.make().p0(),
      dense: true,
      // visualDensity: const VisualDensity(horizontal: -2, vertical: -3),
      // leading: Image(image: AssetImage('assets/images/mmsc_logo.png')),
      leading: Icon(icon),
      minLeadingWidth: 5,
      onTap: () => action, // Here I want the passed navigator function to work.
    );
  }
}

Everything is working here except the onTap Action Method, I don't understand, should I declare the variable as Function or something else?

CodePudding user response:

You just need to create a type into your widget and use it as a constructor parameter.

E.g.:

//here declare the type
typedef TypeNameYouWant = void Function();

class AppDrawerListTile extends StatelessWidget {
  final String title;
  final IconData icon;
  final TypeNameYouWant action; //here use the type declared
  const AppDrawerListTile({
    Key? key,
    required this.title,
    required this.icon,
    required this.action,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
        return ListTile(
          minVerticalPadding: 0,
          title: title.text.make().p0(),
          dense: true,
      // visualDensity: const VisualDensity(horizontal: -2, vertical: -3),
      // leading: Image(image: AssetImage('assets/images/mmsc_logo.png')),
      leading: Icon(icon),
      minLeadingWidth: 5,
      onTap: () => action(), // Here you use your action param like a fn
    );
  }
}

CodePudding user response:

Use VoidCallback instead of function

final VoidCallback action;

CodePudding user response:

Just add ( ) on action in AppDrawerListTile class, and the code should be

onTap: () => action(),

Full code

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

  @override
  Widget build(BuildContext context) {
    return ListTile(
      minVerticalPadding: 0,
      title: title.text.make().p0(),
      dense: true,
      // visualDensity: const VisualDensity(horizontal: -2, vertical: -3),
      // leading: Image(image: AssetImage('assets/images/mmsc_logo.png')),
      leading: Icon(icon),
      minLeadingWidth: 5,
      onTap: () => action(), // Here I want the passed navigator function to work.
    );
  }
}

Why?

If there is no () sign it means that onTap calls anonymous function that returns action and does not call action.

() => action // returns action

// similar to
(){
 return action;
}

And if you add () sign it means that onTap calls anonymous function and the anonymous function calls action function.

() => action() // calls action

// similar to
(){
  action();
}
  • Related