Asynchronous 如何从future获取使用列表并在listView中使用它

Asynchronous 如何从future获取使用列表并在listView中使用它,asynchronous,flutter,future,Asynchronous,Flutter,Future,我正在尝试获取某个目录中所有文件的列表 我从一个名为getUserVideos()的未来函数中获取文件,如果我在函数内部尝试打印数据,我可以看到结果,但不能在函数外部使用数据 class _mediaUtentiState extends State<mediaUtenti> { var lightBlue = Color.fromRGBO(0, 197, 205, 1.0); var _imagesDir; @override void initState()

我正在尝试获取某个目录中所有文件的列表

我从一个名为
getUserVideos()
的未来函数中获取文件,如果我在函数内部尝试打印数据,我可以看到结果,但不能在函数外部使用数据

class _mediaUtentiState extends State<mediaUtenti> {
  var lightBlue = Color.fromRGBO(0, 197, 205, 1.0);
  var _imagesDir;


  @override
  void initState() {
    super.initState();
    getUsersVideos();
  }

  List<String> Names = [
    'Abhishek',
    'John',
    'Robert',
    'Shyam',
    'Sita',
    'Gita',
    'Nitish'
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: lightBlue,
      appBar: new AppBar(
        title: Row(
          mainAxisAlignment: MainAxisAlignment.end,
          children: [
            Container(padding: const EdgeInsets.all(8.0), child: Text('Nome')),
            Container(
              child: CircleAvatar(
                backgroundImage: NetworkImage('http://i.pravatar.cc/300'),
              ),
            ),
          ],
        ),
        backgroundColor: purple,
      ),

      body: new Container(
        child: new ListView.builder(
          reverse: false,
          itemBuilder: (_, int index) => EachList(this.Names[index]),
          itemCount: this.Names.length,
        ),
      ),
    );
  }

  Future<String> getUsersVideos() async {
    print('something');
    final Directory extDir = await getExternalStorageDirectory();
    final String dirPath = '${extDir.path}/Movies/Veople';
    final myDir = new Directory(dirPath);
    List<FileSystemEntity> _images;
    _images = myDir.listSync(recursive: true, followLinks: false);
    print(_images.length);
    _imagesDir = _images;
  }
}

class EachList extends StatelessWidget {
  final String name;
  EachList(this.name);
  @override
  Widget build(BuildContext context) {
    return new Card(
      child: new Container(
        padding: EdgeInsets.all(8.0),
        child: new Row(
          children: <Widget>[
            new CircleAvatar(
              child: new Text(name[0]),
            ),
            new Padding(padding: EdgeInsets.only(right: 10.0)),
            new Text(
              name,
              style: TextStyle(fontSize: 20.0),
            )
          ],
        ),
      ),
    );
  }
}
class\u mediatentistate扩展状态{
var lightBlue=颜色。来自RGBO(0,197,205,1.0);
var_imagesDir;
@凌驾
void initState(){
super.initState();
getUsersVideos();
}
列表名称=[
"阿披实",,
“约翰”,
“罗伯特”,
“Shyam”,
“Sita”,
“吉塔”,
“尼蒂什”
];
@凌驾
小部件构建(构建上下文){
返回脚手架(
背景颜色:浅蓝色,
appBar:新的appBar(
标题:世界其他地区(
mainAxisAlignment:mainAxisAlignment.end,
儿童:[
容器(padding:const EdgeInsets.all(8.0),child:Text('Nome')),
容器(
孩子:圆环星(
背景图片:NetworkImage('http://i.pravatar.cc/300'),
),
),
],
),
背景颜色:紫色,
),
主体:新容器(
子项:新建ListView.builder(
反面:错,
itemBuilder:(z,int index)=>EachList(this.Names[index]),
itemCount:this.Names.length,
),
),
);
}
未来的getUsersVideos()异步{
打印(‘某物’);
最终目录extDir=wait getExternalStorageDirectory();
最后一个字符串dirPath='${extDir.path}/Movies/Veople';
final myDir=新目录(dirPath);
列出图片;
_images=myDir.listSync(递归:true,followLinks:false);
打印(图像长度);
_imagesDir=_图像;
}
}
类EachList扩展了无状态小部件{
最后的字符串名;
每个列表(此名称);
@凌驾
小部件构建(构建上下文){
归还新卡(
子容器:新容器(
填充:边缘设置。全部(8.0),
孩子:新的一排(
儿童:[
新圆星(
子项:新文本(名称[0]),
),
新填充(填充:仅限边集(右:10.0)),
新文本(
名称
样式:TextStyle(fontSize:20.0),
)
],
),
),
);
}
}
现在我只显示一个名称列表,但我想为路径中的每个文件显示一张卡片

例如,在函数
getUserVideos()
中,当我尝试打印
imagesDir
时,我得到了正确的结果
[文件:'/storage/emulated/0/Movies/Veople/1556217605345.mp4',文件:'/storage/emulated/0/Movies/Veople/1556205176345.png',文件:'/storage/emulated/0/Movies/Veople/1556217632709.mp4',文件:
...]
但我无论如何都无法从该函数中访问imageDir

class _mediaUtentiState extends State<mediaUtenti> {
  var lightBlue = Color.fromRGBO(0, 197, 205, 1.0);
  var _imagesDir;


  @override
  void initState() {
    super.initState();
    getUsersVideos();
  }

  List<String> Names = [
    'Abhishek',
    'John',
    'Robert',
    'Shyam',
    'Sita',
    'Gita',
    'Nitish'
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: lightBlue,
      appBar: new AppBar(
        title: Row(
          mainAxisAlignment: MainAxisAlignment.end,
          children: [
            Container(padding: const EdgeInsets.all(8.0), child: Text('Nome')),
            Container(
              child: CircleAvatar(
                backgroundImage: NetworkImage('http://i.pravatar.cc/300'),
              ),
            ),
          ],
        ),
        backgroundColor: purple,
      ),

      body: new Container(
        child: new ListView.builder(
          reverse: false,
          itemBuilder: (_, int index) => EachList(this.Names[index]),
          itemCount: this.Names.length,
        ),
      ),
    );
  }

  Future<String> getUsersVideos() async {
    print('something');
    final Directory extDir = await getExternalStorageDirectory();
    final String dirPath = '${extDir.path}/Movies/Veople';
    final myDir = new Directory(dirPath);
    List<FileSystemEntity> _images;
    _images = myDir.listSync(recursive: true, followLinks: false);
    print(_images.length);
    _imagesDir = _images;
  }
}

class EachList extends StatelessWidget {
  final String name;
  EachList(this.name);
  @override
  Widget build(BuildContext context) {
    return new Card(
      child: new Container(
        padding: EdgeInsets.all(8.0),
        child: new Row(
          children: <Widget>[
            new CircleAvatar(
              child: new Text(name[0]),
            ),
            new Padding(padding: EdgeInsets.only(right: 10.0)),
            new Text(
              name,
              style: TextStyle(fontSize: 20.0),
            )
          ],
        ),
      ),
    );
  }
}
我确信用几条线就可以解决这个问题,但现在是3个小时,我找不到解决方案


谢谢

我想这肯定已经得到了回答,但尽管有很多关于FutureBuilder和List的问题,但没有一个是这样的或者没有得到充分的回答

我会这样做:

导入'dart:io';
进口“包装:颤振/材料.省道”;
导入“package:path_provider/path_provider.dart”;
Future\u getUsersVideos()异步{
打印(‘某物’);
最终目录extDir=wait getExternalStorageDirectory();
最后一个字符串dirPath='${extDir.path}/Movies/Veople';
final myDir=新目录(dirPath);
List _images=myDir.listSync(递归:true,followLinks:false);
返回图像;
}
类ListFromFuture扩展StatefulWidget{
@凌驾
_ListFromFutureState createState()=>\u ListFromFutureState();
}
类_ListFromFutureState扩展状态{
未来;
@凌驾
void initState(){
super.initState();
future=_getUsersVideos();
}
@凌驾
小部件构建(构建上下文){
回归未来建设者(
未来:未来,,
生成器:(上下文,快照){
交换机(快照.连接状态){
案例连接状态。无:
案例连接状态。正在等待:
案例连接状态.active:
返回容器(
对齐:对齐.center,
子项:文本(“加载”),
);
打破
案例连接状态。完成:
if(snapshot.hasError){
//返回您对此案例所做的任何操作,可能是一个错误
返回容器(
对齐:对齐.center,
子项:文本(“错误:${snapshot.Error}”),
);
}
var data=snapshot.data;
返回新的ListView.builder(
反面:错,
itemBuilder:(_,int index)=>EachList(数据[索引]),
itemCount:data.length,
);
打破
}
},
);
}
}
其中的重要部分是:

  • future只是将其设置为initState,而不是build函数。这确保不会在每次小部件构建时调用它
  • 我处理所有可能出现错误或未来尚未完成的情况

  • 不过,老实说,您的示例实际上非常接近于使其工作。您所要做的就是将您设置的
    \u imagesDir=images
    行包装在
    setState(()=>…)
    中,它应该可以工作(假设列表没有返回空)。您还应该检查_imagesDir==null,否则可能会出现null指针异常。

    谢谢您的回复,我一到家就会尝试。