2

I want to instantiate a Widget based on an int.

const List<Widget> WIDGETS = <Widget>[
  Widget1,
  Widget2,
  Widget3,
  Widget4,
];

final int index = 1;

Navigator.pushReplacement(context, MaterialPageRoute<Widget>(builder: (BuildContext context) => WIDGETS[index](hey: index))));

However, I am getting the following error in the Widget list:

The element type 'Type' can't be assigned to the list type 'Widget'. dart(list_element_type_not_assignable)

I don't want to use dynamic or something similar, is there any way to declare that these are Widget Types?

The JS similar would be typeof.


This is possible:

void a() {
  print('a');
}

void b() {
  print('b');
}

const List<Function> EXAM_SCREENS = <Function>[
  a,
  b,
  a,
  a,
];

Why isn't my scenario as such?

Edit: Just to clarify, I need to pass dynamic arguments to these widgets. Widget1 needs the hey argument which is generated in its own Widget.

5
  • Are you init the Widgets? From what you write you're passing a list of Types, if you would like to init you need to call its constructor like this Widget1() Commented Apr 15, 2020 at 15:46
  • I'm going to answer Commented Apr 15, 2020 at 15:47
  • @LorenzoImperatrice I edited my question if it helps, thanks in advance :) Commented Apr 15, 2020 at 15:55
  • Didn't saw it sorry, i'm going to update my answere now, anyway what do u mean with "dynamic arguments" ?? Commented Apr 15, 2020 at 16:00
  • The index is generated in another Widget, I don't have access to it until the Navigator.pushReplacement function is called. Commented Apr 15, 2020 at 16:05

1 Answer 1

1

Because they are not Widget until you initialize them, instead functions doesn't need to be initialized as they act like a variable (you are passing the pointer to the function).

So in this way:

const List<Widget> WIDGETS = <Widget>[
  Widget1,
  Widget2,
  Widget3,
  Widget4,
];

you're storing a list of Type, then if you try to change them like this you'll not get any errors.

const List<Type> WIDGETS = <Type>[
  Widget1,
  Widget2,
  Widget3,
  Widget4,
];

For doing what you ask is necessary to radically change the approach by using a method to create the desired widget, to this method pass the index as parameter (or any parameters needed for choose the right widget to create) and, based on the parameters, the method will return the right Widget.

Widget _chooseTheRightOne(int index, dynamic hey) {
  switch(index) {
     case 0: Widget1(hey: hey); break;
     case 1: Widget2(hey: hey); break;
  }
}
Sign up to request clarification or add additional context in comments.

7 Comments

But how you will initialise these ? It will throw error here WIDGETS[index](hey: index)
Just as @MidhunMP said, The expression doesn't evaluate to a function, so it can't be invoked.
You have to radically change the approach by using the factory pattern, or factory method pattern. You pass the index and the method create and return the object for you.
Using a method would make me remove the const keyword, allocating the Widgets every time I call the method. I want to get the item from the list without having to allocate it every single time.
This is the most clean way to do it. If you prefere you can make a list of already allocated widget with a GlobalKeyassociated to them to access instance variables and modify them.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.