How to implement Voidcallback in a List of Items to list in a Gridview?

Asked

Viewed 46 times

0

I tried to follow the tutorial of this link http://www.macoratti.net/19/07/flut_gridv1.htm because it has a list of items in gridview closer than I want to use.

And then I tried to add an option to make these items clickable and made some small modifications but is giving error in option Voidcallback.

The error returned are these:

  1. Invalid constant value - line 38
  2. The values in a const list literal must be constants - line 38
  3. Const variables must be initialized with a constant value - line 38

The part of the code that’s going wrong is this:

class ItemExemplo {
  const ItemExemplo({this.titulo, this.icon, this.onPressBtn});
  final String titulo;
  final IconData icon;
  final VoidCallback onPressBtn;
}

const List<ItemExemplo> itenslist = const <ItemExemplo>[
  const ItemExemplo(titulo: 'Carro', icon: Icons.directions_car),
  const ItemExemplo(titulo: 'Bike', icon: Icons.directions_bike),
  const ItemExemplo(titulo: 'Barco', icon: Icons.directions_boat),

  // o onPressBtn da linha abaixo é onde esta dando o erro, mas preciso dele pra função onTap do Widget que será exibido no grid.

  const ItemExemplo(titulo: 'Ônibux', icon: Icons.directions_bus, onPressBtn: () => print("Teste")),
];

I even understand that the error is in the constants, but am I on the right path or should I redo it in a totally different way? There’s another way to do it that works?

As there is not yet a snippet to flutter here in the OS I put the complete code in Dartpad in the link below:

https://dartpad.dev/96d51e9f55496f4125ab6697d1a639e4

2 answers

3

I chose the above answer of Matheus as correct for being just the answer to my question. But I found another solution to my problem and solved it in the form below, so the two answers are correct for those who need it in the future.

In my solution I deleted the listing lines and modified the constructor of the Itenscard widget as follows, adding in addition to callback also put another option for icon colors:

class ItensCard extends StatelessWidget {
  ItensCard({this.title, this.icon, this.colorItem, this.onPressBtn});

  final String title;
  final IconData icon;
  final MaterialColor colorItem;
  final VoidCallback onPressBtn;

  @override
  Widget build(BuildContext context) {
    final TextStyle textStyle = Theme.of(context).textTheme.bodyText2;
    return Card(
        color: Colors.white,
        child: InkWell(
          onTap: onPressBtn,
          splashColor: Colors.amber,
          child: Center(
            child: Column(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  Icon(icon, size: 80.0, color: colorItem),
                  Text(title, style: textStyle),
                ]),
          ),
        ));
  }
}

And now instead of me using the gridview listing as I did before in this way:

 children: List.generate(itenslist.length, (index) {
      return Center(
        child: ItensCard(item: itenslist[index]),
      );
    }),

Now I add the own direct list in gridview this way:

children: <Widget>[
    ItensCard(title: 'Carro', icon: Icons.directions_car, colorItem: Colors.blue, onPressBtn: () => print("Teste Carro")),
    ItensCard(title: 'Bike', icon: Icons.directions_bike, colorItem: Colors.red, onPressBtn: () => print("Teste Bike")),
    ItensCard(title: 'Barco', icon: Icons.directions_boat, colorItem: Colors.pink, onPressBtn: () => print("Teste Barco")),
    ItensCard(title: 'Ônibus', icon: Icons.directions_bus, ncolorItem: Colors.green, onPressBtn: () => print("Teste Ônibus")),
  ]);

This for me in my case saved me more lines of code greatly reducing the size, and also made my job easier. I don’t know if it’s useful to everyone but it’s been very useful to me.

Follow the solution link for viewing on Dartpad:

https://dartpad.dev/96d51e9f55496f4125ab6697d1a639e4

0


As you may notice, the problem is related to constants.

You can resolve leaving your callback also constant, as follows:

void onClick() {
  print("Teste");
}

const List<ItemExemplo> itenslist = [
  ItemExemplo(titulo: 'Carro', icon: Icons.directions_car),
  ItemExemplo(titulo: 'Bike', icon: Icons.directions_bike),
  ItemExemplo(titulo: 'Barco', icon: Icons.directions_boat),
  ItemExemplo(
      titulo: 'Ônibux',
      icon: Icons.directions_bus,
      onPressBtn: onClick)
];

Another point that can be improved is in the class ItensCard:

class ItensCard extends StatelessWidget {
  const ItensCard({Key key, this.item}) : super(key: key);
  final ItemExemplo item;
  @override
  Widget build(BuildContext context) {
    final TextStyle textStyle = Theme.of(context).textTheme.bodyText2;
    return Card(
        color: Colors.white,
        child: InkWell(
          onTap: () => item.onPressBtn(),
          splashColor: Colors.amber,
          child: Center(
            child: Column(
                mainAxisSize: MainAxisSize.min,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: <Widget>[
                  Icon(item.icon, size: 80.0, color: textStyle.color),
                  Text(item.titulo, style: textStyle),
                ]),
          ),
        ));
  }
}

Change the parameter onTap() as follows:

onTap: item.onPressBtn,

Only items that own the property onPressBtn filled will have the click effect, so it will not generate errors if the property is null.

  • Thanks for answering, but it’s not working yet, it solves the question when callback runs just a simple print, but if I try to use another method as a Navigator.of(context).push he of the other mistake of A value of type 'Future<Null>' can't be returned from function 'onClick'. Excuse my ignorance on this subject, I’m still learning about flutter.

  • As you said, it solved your problem, which is what you had doubts about and was specified in your example. Now you are facing another different problem friend.

  • Change your question and add an example of this problem you mentioned regarding Navigator. A tip (Don’t get me wrong), when asking questions, don’t hide information, we still don’t know how to deal with xD crystal balls right

  • 1

    Sorry buddy, as I said I’m still learning about flutter, I thought I’d make a callback from Voidcallback that was used as onPressBtn in a gridview serveria for all types of callbacks as well as in an ontap or an onpress of any widget, did not know that one style would override the other. But I stayed hj all day trying to solve this and I think I found a solution, I will post Aja. Even so thank you and forgive my mistakes.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.