Future<Widget> can't be assigned to the list type 'widget'

Issue

I’m making a dialog screen which contains some dropbox and list view like below.

showDialog(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
            content: StatefulBuilder(
              builder: (BuildContext DialogContext, StateSetter setState) {
                return Column(
                  children: [
                    Dropdown(DialogContext, setState, 0, ReceiveArgs, _lListOfDepthList), 
                    Dropdown(DialogContext, setState, 1, ReceiveArgs, _lListOfDepthList),                        
                    FutureListView(ReceiveArgs),                                            
                  ],
                );
              },
            ),
          );
        });

And since I called a Furture function, SetName, I change ‘FutureListView’ to Future function, too.
FutureListView code is below.

       
  Future<Widget> FutureListView(ArgumentClass ReceiveArgs) async{
    String SelectedFullAddress = GetSelectedAddress(5, "");

    _Name = await SetName(ReceiveArgs.lFullList, SelectedFullAddress);

    if (_Name.isNotEmpty) {
      print("ListView!");
      return ListView.builder(
        itemCount: _Name.length,
        itemBuilder: (context, index) {
          return CheckboxListTile(
            title: Text(_Name[index]),
            value: null,
            onChanged: null,
          );
        },
      );
    } else {
      print("List Null");
      return Text("");
    }
  }

However after the change, I got a compile error below.

error: The element type ‘Future’ can’t be assigned to the list type ‘Widget’. (list_element_type_not_assignable at [checker_v2])

Could you help me to solve this problem?

Meanwhile I used StatefulBuilder because other Dropdownbutton widgets interact each other.

Thank you!

Solution

Use a FutureBuilder.

Here’s how your FutureListView should look like (you can change the name of the method now)

 Future<String> FutureListView(ArgumentClass ReceiveArgs) async{
        String SelectedFullAddress = GetSelectedAddress(5, "");
  
        return await SetName(ReceiveArgs.lFullList, SelectedFullAddress);
      }

And, this should be your showDialog

showDialog(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
            content: StatefulBuilder(
              builder: (BuildContext DialogContext, StateSetter setState) {
                return Column(
                  children: [
                    Dropdown(DialogContext, setState, 0, ReceiveArgs, _lListOfDepthList),
                    Dropdown(DialogContext, setState, 1, ReceiveArgs, _lListOfDepthList),
                    FutureBuilder<String>(
                    future: FutureListView(ReceiveArgs),
                    builder: (context, snapshot) => {
                      if(!snapshot.hasData) return Container(); // This container can be a loading screen, since its waiting for data.

                      if(snapshot.data.isNotEmpty){
                        print("ListView!");
                        return ListView.builder(
                          itemCount: _Name.length,
                          itemBuilder: (context, index) {
                            return CheckboxListTile(
                              title: Text(_Name[index]),
                              value: null,
                              onChanged: null,
                              );
                            },
                          );,
                        } else {
                          print("List Null");
                          return Text("");
                      },
                    )
                  ],
                );
              },
            ),
          );
        });

FutureBuilder’s future won’t wait until the async method is completed, but try to build the builder method until it is. You can use snapshot.hasData to check if the async method has returned something already, and if it doesn’t, you can show a loading screen if you want. Then, use snapshot.data to access the result of your future.

Answered By – Delynith

Answer Checked By – Timothy Miller (FlutterFixes Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *