Future<Widget> 不能分配给列表类型“widget”

问题描述

我正在制作一个对话框屏幕,其中包含一些下拉框和列表视图,如下所示。

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

由于我调用一个 Furture 函数 SetName,所以我也将“FutureListView”更改为 Future 函数。 FutureListView 代码如下。

       
  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("");
    }
  }

但是在更改之后,我在下面遇到了编译错误

错误:无法将元素类型“未来”分配给列表类型“小部件”。 (list_element_type_not_assignable 在 [checker_v2])

你能帮我解决这个问题吗?

同时我使用 StatefulBuilder 因为其他 Dropdownbutton 小部件相互交互。

谢谢!

解决方法

您需要使用 Future 将小部件包装到 FutureBuilder

FutureBuilder<TypeOfName>(
  future: getName(),builder (context,snapshot) {
    // Data is not loading,you should show progress indicator to user
    if (!snapshot.hasData) {
      return CircularProgressIndicator();
    }
    // Data from Future is loaded
    final name = snapshot.data;
    if (name.isEmpty) {
      return Text('');
    } else {
      return ListView.builder(
        itemCount: name.length,itemBuilder: (context,index) {
          return CheckboxListTile(
            title: Text(name[index]),value: null,onChanged: null,);
        },);
    }
  }
);

getName() 方法:

Future<TypeOfName> getName() {
  String SelectedFullAddress = GetSelectedAddress(5,"");
  return SetName(ReceiveArgs.lFullList,SelectedFullAddress);
}

并将 TypeOfName 替换为 _Name 变量的类型(您不能声明它)。

,

使用 FutureBuilder

您的 FutureListView 应如下所示(您现在可以更改方法的名称)

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

而且,这应该是你的 showDialog

showDialog(
        context: context,builder: (BuildContext context) {
          return AlertDialog(
            content: StatefulBuilder(
              builder: (BuildContext DialogContext,StateSetter setState) {
                return Column(
                  children: [
                    Dropdown(DialogContext,setState,ReceiveArgs,_lListOfDepthList),Dropdown(DialogContext,1,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,index) {
                            return CheckboxListTile(
                              title: Text(_Name[index]),);
                            },);,} else {
                          print("List Null");
                          return Text("");
                      },)
                  ],);
              },),);
        });

FutureBuilder 的未来不会等到异步方法完成,而是尝试构建构建器方法,直到它完成。您可以使用 snapshot.hasData 检查异步方法是否已经返回某些内容,如果没有,您可以根据需要显示加载屏幕。然后,使用 snapshot.data 访问您未来的结果。

,

使用类型 Widget 而不是 Future,因为您不能直接在小部件设计中调用 Future。

您可以像这样简单地修改您的代码。

  Widget FutureListView(ArgumentClass receiveArgs) {
    String SelectedFullAddress = GetSelectedAddress(5,"");
    _Name = await SetName(receiveArgs.lFullList,SelectedFullAddress);
    if (_Name.isNotEmpty) {
    bool _isChecked = false;

    print("ListView!");
      return ListView.builder(
        itemCount: 3,shrinkWrap: true,index) {
          return  CheckboxListTile(
            value: _isChecked,title: Text(_Name[index]),onChanged: (bool value) {
              setState(() {
                _isChecked = value;
              });
            },);
    } else {
      print("List Null");
      return Text("");
    }
  }