asynchronous - 如何从未来使用列表并在 listView 中使用它
问题描述
我正在尝试获取某个目录中所有文件的列表。
我从调用的未来函数中获取文件,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),
)
],
),
),
);
}
}
现在我只显示一个名称列表,但我想为路径中的每个文件显示一张卡片。
例如,在getUserVideos()
我尝试打印的函数中,imagesDir
我得到了正确的结果[File: '/storage/emulated/0/Movies/Veople/1556217605345.mp4', File: '/storage/emulated/0/Movies/Veople/1556217605345.png', File: '/storage/emulated/0/Movies/Veople/1556217632709.mp4', File:
...]
但是我不能以任何方式从该函数中访问 _imageDir。
我确信用几行代码就可以解决这个问题,但现在是 3 个小时,我无法得到解决方案。
谢谢!
解决方案
我认为肯定已经回答了这个问题,但是虽然有很多关于 FutureBuilder 和 Lists 的问题,但没有一个是这样的,或者没有真正得到充分的回答。
这就是我的做法:
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
Future<List<FileSystemEntity>> _getUsersVideos() async {
print('something');
final Directory extDir = await getExternalStorageDirectory();
final String dirPath = '${extDir.path}/Movies/Veople';
final myDir = new Directory(dirPath);
List<FileSystemEntity> _images = myDir.listSync(recursive: true, followLinks: false);
return _images;
}
class ListFromFuture extends StatefulWidget {
@override
_ListFromFutureState createState() => _ListFromFutureState();
}
class _ListFromFutureState extends State<ListFromFuture> {
Future<List<FileSystemEntity>> future;
@override
void initState() {
super.initState();
future = _getUsersVideos();
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: future,
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
case ConnectionState.waiting:
case ConnectionState.active:
return Container(
alignment: Alignment.center,
child: Text("Loading"),
);
break;
case ConnectionState.done:
if (snapshot.hasError) {
// return whatever you'd do for this case, probably an error
return Container(
alignment: Alignment.center,
child: Text("Error: ${snapshot.error}"),
);
}
var data = snapshot.data;
return new ListView.builder(
reverse: false,
itemBuilder: (_, int index) => EachList(data[index]),
itemCount: data.length,
);
break;
}
},
);
}
}
其中的重要部分是:
- future 只是设置它 initState,而不是构建函数。这确保每次构建小部件时都不会调用它
- 我处理所有有错误或未来尚未完成的情况。
不过老实说,您的示例实际上非常接近使其正常工作。您所要做的就是将您_imagesDir = images
在 a中设置的行换行,setState(() => ...)
它应该可以工作(假设列表不返回空)。不过,您还应该检查 _imagesDir == null ,否则您可能会遇到空指针异常。
推荐阅读
- winapi - 用户注销时是否发送 WM_DESTROY?
- python - Python pandas:在数据透视表上应用滚动总和
- python - spyder 3.7 偶尔没有响应
- java - 如何使用嵌套方法模拟具有多个 && 条件的布尔变量?用于单元测试的 MOCKITO
- c++ - 矩阵填充,但它每行跳过一个元素,为什么?
- javascript - 数据表 - 显示来自两个数组的数据
- java - Sonar-Java如何获取变量类的注释
- twilio - 如何订阅 twilio number 的错误信息?
- javascript - PHP 将简单的 3 行 JavaScript 转换为等效的 PHP
- c++ - C ++使用函数获取向量内对象的引用