在 Flutter 中,如何确保用于构建 GridView 的数据可用?
In Flutter, How can I make sure that the data used to build a GridView is available?
我有一组文件存储在应用程序目录中。每个都包含要在 GridView 小部件中显示的 Uint8List 数据。由于 Dart 的异步特性,我如何才能确保在 Widget 构建开始之前能够获得可用的文件数和文件名。由于files/names的数字是动态的,所以我不得不扫描App目录。以下是部分代码片段。我把获取文件名和生成Uint8List数据集的功能放在了initState中,但有时不能正常使用。感谢对此问题的任何反馈。
class _PageAState extends State<PageA> {
List<String> fileNames=[];
List<Uint8List> uIntData
int numFiles=0;
/*get file names (starting with "XYZ", stored in App directory*/
_getFileName() async {
fileNames = [];
String keyWord = "XYZ";
List files = new List();
// var lock = new Lock(); // try https://pub.dev/packages/synchronized package with no luck
// await lock.synchronized(() async {
String directory = (await getApplicationDocumentsDirectory()).path;
files = Directory("$directory").listSync();
for (FileSystemEntity f in files) {
if (f.path.contains(keyWord)) {
fileNames.add(f.path);
print(f.path);
}
}
// });
}
/*get a set of Uint8List data */
_getImageData() async {
await _getFileName();
numFiles = fileNames.length;
for (int i = 0; i < numFiles; i++) {
Uint8List dData =
(await rootBundle.load(fileNames[i])).buffer.asUint8List();
uIntData.add(dData);
}
}
@override
initState() {
super.initState();
/** load Uint8List data set async ***/
_getImageData();
}
Widget buildGridView(BuildContext context) {
var orientation = Orientation.portrait;
return (GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: (orientation == Orientation.portrait) ? 2 : 3),
// how to make sure that numFiles is properly set ???
itemCount: numFiles,
itemBuilder: (BuildContext ctx, int index) {
return Padding(
padding: EdgeInsets.all(20),
child: Stack(children: <Widget>[
GestureDetector(
child: Card(
shape: Border.all(
width: 5,
),
elevation: 20,
color: Colors.greenAccent,
child: SizedBox(
child: (uIntData.isEmpty || uIntData[index] == null)
? CircularProgressIndicator()
: Image.memory(uIntData[index]),
width: 120,
height: 120,
),
),
onTap: () {
},
onLongPress: () {
},
),
]),
);
},
));
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: buildGridView(context),
);
}
}
您必须初始化 uIntData 和 itemCount 使用您的 uIntData 列表的长度,例如:
声明:
List<Uint8List> uIntData = [];
计算实物:
itemCount: uIntData.length,
此外,您可以仅用一种方法重构 _getFileName 和 _getImageData,因为当您只能使用一种方法时,您使用 2 作为 bucle .
检索所有文件后再次尝试刷新 UI:
@override
initState() {
super.initState();
/** load Uint8List data set async ***/
_getImageData().then((){
setState(() {});
});
}
我有一组文件存储在应用程序目录中。每个都包含要在 GridView 小部件中显示的 Uint8List 数据。由于 Dart 的异步特性,我如何才能确保在 Widget 构建开始之前能够获得可用的文件数和文件名。由于files/names的数字是动态的,所以我不得不扫描App目录。以下是部分代码片段。我把获取文件名和生成Uint8List数据集的功能放在了initState中,但有时不能正常使用。感谢对此问题的任何反馈。
class _PageAState extends State<PageA> {
List<String> fileNames=[];
List<Uint8List> uIntData
int numFiles=0;
/*get file names (starting with "XYZ", stored in App directory*/
_getFileName() async {
fileNames = [];
String keyWord = "XYZ";
List files = new List();
// var lock = new Lock(); // try https://pub.dev/packages/synchronized package with no luck
// await lock.synchronized(() async {
String directory = (await getApplicationDocumentsDirectory()).path;
files = Directory("$directory").listSync();
for (FileSystemEntity f in files) {
if (f.path.contains(keyWord)) {
fileNames.add(f.path);
print(f.path);
}
}
// });
}
/*get a set of Uint8List data */
_getImageData() async {
await _getFileName();
numFiles = fileNames.length;
for (int i = 0; i < numFiles; i++) {
Uint8List dData =
(await rootBundle.load(fileNames[i])).buffer.asUint8List();
uIntData.add(dData);
}
}
@override
initState() {
super.initState();
/** load Uint8List data set async ***/
_getImageData();
}
Widget buildGridView(BuildContext context) {
var orientation = Orientation.portrait;
return (GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: (orientation == Orientation.portrait) ? 2 : 3),
// how to make sure that numFiles is properly set ???
itemCount: numFiles,
itemBuilder: (BuildContext ctx, int index) {
return Padding(
padding: EdgeInsets.all(20),
child: Stack(children: <Widget>[
GestureDetector(
child: Card(
shape: Border.all(
width: 5,
),
elevation: 20,
color: Colors.greenAccent,
child: SizedBox(
child: (uIntData.isEmpty || uIntData[index] == null)
? CircularProgressIndicator()
: Image.memory(uIntData[index]),
width: 120,
height: 120,
),
),
onTap: () {
},
onLongPress: () {
},
),
]),
);
},
));
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: buildGridView(context),
);
}
}
您必须初始化 uIntData 和 itemCount 使用您的 uIntData 列表的长度,例如:
声明:
List<Uint8List> uIntData = [];
计算实物:
itemCount: uIntData.length,
此外,您可以仅用一种方法重构 _getFileName 和 _getImageData,因为当您只能使用一种方法时,您使用 2 作为 bucle .
检索所有文件后再次尝试刷新 UI:
@override
initState() {
super.initState();
/** load Uint8List data set async ***/
_getImageData().then((){
setState(() {});
});
}