Flutter无法在应用程序的第一页上显示异步调用的信息



更新

我能够使用FutureBuilder小部件来解决我的问题。所有更改都在file_listing.art文件中。这是更新后的文件:

开始file_listing.dart

import 'package:flutter/material.dart';
import 'dart:async';
import 'package:path/path.dart' as pathpkg;
import 'package:pythonga_expense_estimator/components/bottom_button.dart';
import 'package:pythonga_expense_estimator/services/directory_services.dart';
class FileListing extends StatefulWidget {
FileListing();
@override
State<FileListing> createState() => _FileListingState();
}
class _FileListingState extends State<FileListing> {
Map fileMap = {};
Future<Map> getSavedEstimates() async {
try {
var savedEstimates = await DirectoryHelper.listOfFiles().then((resp) {
return resp;
});
savedEstimates.forEach((key, value) => print(key));
return savedEstimates;
} catch (e) {
throw Exception("Could Not Retrieve list of saved files");
}
}

Future<List<Widget>> fileListMappedAsWidget() async {
var fileHits =
await getSavedEstimates(); //returns Future<Map<dynamic,dynamic>>
List<Widget> newList = [];
fileHits.forEach((k, v) {
newList.add(Row(
children: [
Text(pathpkg.basename(v)),
BottomButton(
buttonTitle: 'Delete',
onPressed: () => () {
setState(() {
k.deleteSync();
fileMap.remove(k);
});
})
],
));
});
// () => newList;
return newList;
// throw ("f");
}
@override

Widget build(BuildContext context) {
return Container(
child: FutureBuilder(
future: fileListMappedAsWidget(),
// future: testRetrieve,
builder: (BuildContext context, AsyncSnapshot<List> snapshot) {
List<Widget> children;
print(snapshot.connectionState);
if (snapshot.hasData) {
List<Widget> childStuff = [];
for (int i = 0; i < snapshot.data!.length; i++) {
childStuff.add(snapshot.data![i]);
}
children = childStuff;
} else if (snapshot.hasError) {
children = <Widget>[
const Icon(Icons.error_outline, color: Colors.red, size: 60),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Text('Error: ${snapshot.error}'))
];
} else {
children = const <Widget>[
SizedBox(
width: 60, height: 60, child: CircularProgressIndicator()),
Padding(
padding: EdgeInsets.only(top: 16),
child: Text('Awaiting Result'),
)
];
}
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: children,
),
);
}),
);
}
}

file_listing.dart结束

原始问题

我正在尝试为Flutter应用程序创建一个页面。这将是用户启动应用程序时看到的第一个页面。

该页面将显示文件列表、用户先前保存的成本估计以及用于创建新的"文件"的按钮;估计";然后也可以将其保存到文件中。

文件保存在设备上,我使用path_provider和path包来访问它们。对设备文件系统的读取和写入是异步操作。

我无法在页面加载时自动显示文件列表,我想了解如何做到这一点。async函数的结果是数据类型的未来,我不能让它们只是数据类型。

以下是我的代码:

(1(主要飞镖

它将材料应用程序的主页指定为StartPage((。

主飞镖的启动

import 'package:flutter/material.dart';
import 'constants/text_constants.dart';
import 'pages/start_page.dart';
void main() => runApp(PythongaVisitCostCalculator());
class PythongaVisitCostCalculator extends StatelessWidget {
const PythongaVisitCostCalculator({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: kAppTitle1,
theme: ThemeData(
primarySwatch: Colors.lightBlue,
elevatedButtonTheme: ElevatedButtonThemeData(
style: ButtonStyle(
shape: MaterialStateProperty.all<OutlinedBorder>(
RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50.0),
),
),
),
),
),
home: StartPage(title: kYourTripsDescr));
}
}

主镖末端

(2(start_page.dart

这是应用程序的主页(有状态类(,如main.dart中所指定。显示的项目之一是用户使用FileList((小部件保存的文件列表,该小部件在file_listing.art文件中创建,如下所示。

开始start_page.dart

import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:pythonga_expense_estimator/components/round_icon_button.dart';
import 'package:pythonga_expense_estimator/components/file_listing.dart';
import 'package:pythonga_expense_estimator/pages/input_page.dart';
import '../constants/text_constants.dart';

class StartPage extends StatefulWidget {
const StartPage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<StartPage> createState() => _StartPageState();
}
class _StartPageState extends State<StartPage> {
Map fileList = {};
@override
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text(kAppTitle2),
centerTitle: true,
automaticallyImplyLeading: false,
),
body: SafeArea(
child: Column(children: [
Text(kYourEstimatesDescr),
FileListing(),
Row(
children: [
Text(kEstimateTripDescr),
RoundIconButton(
icon: FontAwesomeIcons.plus,
onPressed: () {
Navigator.push(context,
MaterialPageRoute(builder: (context) {
return InputPage(title: 'New Estimate');
}));
})
],
),
]),
),
);
}
}

start_page.dart结束

(3(file_listing.dart

这个有状态类返回一个小部件FileList((,该小部件在StartPage((小部件中使用。

开始file_listing.dart

import 'package:flutter/material.dart';
import 'package:path/path.dart' as pathpkg;
import 'package:pythonga_expense_estimator/components/bottom_button.dart';
import 'package:pythonga_expense_estimator/services/directory_services.dart';
class FileListing extends StatefulWidget {
FileListing();
@override
State<FileListing> createState() => _FileListingState();
}
class _FileListingState extends State<FileListing> {
Map fileMap = {};
Future<Map> getSavedEstimates() async {
try {
var savedEstimates = await DirectoryHelper.listOfFiles().then((resp) {
return resp;
});
savedEstimates.forEach((key, value) => print(key));
return savedEstimates;
} catch (e) {
throw Exception("Could Not Retrieve list of saved files");
}
}
Future<List<Widget>> fileListMappedAsWidget() async {
var fileHits = await getSavedEstimates();  //returns Future<Map<dynamic,dynamic>>
List<Widget> newList = [];
fileHits.forEach((k, v) {
newList.add(Row(
children: [
Text(pathpkg.basename(v)),
BottomButton(
buttonTitle: 'Delete',
onPressed: () => () {
setState(() {
k.deleteSync();
fileMap.remove(k);
});
})],
));
});
}
@override
Widget build(BuildContext context) {
// if (fileList.isEmpty) {
if (fileListMappedAsWidget().isEmpty) {
return Container(
child: Row(children: const [
Center(child: Text("No Estimates on File")),
]));
}
return Column(
//children: fileList,
children: fileListMappedAsWidget(),
);
}
}

file_listing.dart结束

Dart Analysis在线上给了我一个错误:children:fileListMappedAsWidget((。错误为:

参数类型"Future<列表>'无法分配给参数类型"List"。

如果(fileListMappedAsWidget((.isEmpty({错误为:

没有为类型"Future<"定义getter"isEmpty";列表>

我期望fileListMappedAsWidget的返回将是List而不是Future<列表>一旦异步方法完成并返回其响应。

我的问题是";我该如何改变未来<列表>以便我的页面列出用户保存的文件?

(4(directory_services.dart

以下是directory_services.dart中的代码,它读取应用程序数据文件夹的内容并返回{File,filename text}的映射。此代码似乎工作正常。

启动directory_services.dart

import 'dart:io' as io;
import 'package:path_provider/path_provider.dart' as pathprvdrpkg;
import 'package:path/path.dart' as pathpkg;
import '../constants/text_constants.dart';
class DirectoryHelper {
static Future<Map<io.FileSystemEntity, String>> listOfFiles() async {
List<io.FileSystemEntity> fileSystemEntityList =
io.Directory(await localPath()).listSync();
Map<io.FileSystemEntity, String> fileMap = {};
for (int i = 0; i < fileSystemEntityList.length; i++) {
if (pathpkg.extension(fileSystemEntityList[i].path) ==
kEstimateFileExtension) {
fileMap[fileSystemEntityList[i]] = fileSystemEntityList[i].path;
}
}
return fileMap;
}
static localPath() async {
// finds the correct local path using path_provider package
try {
final directory = await pathprvdrpkg.getApplicationDocumentsDirectory();
// print("directory.path in DirectoryPath.localPath");
return directory.path;
} catch (e) {
return Exception('Error: $e');
}
}
}

directory_services.dart结束

谢谢你的帮助和建议!

我能够使用FutureBuilder小部件解决我的问题。所有更改都在file_listing.art文件中。这是更新后的文件:

开始file_listing.dart

import 'package:flutter/material.dart';
import 'dart:async';
import 'package:path/path.dart' as pathpkg;
import 'package:pythonga_expense_estimator/components/bottom_button.dart';
import 'package:pythonga_expense_estimator/services/directory_services.dart';
class FileListing extends StatefulWidget {
FileListing();
@override
State<FileListing> createState() => _FileListingState();
}
class _FileListingState extends State<FileListing> {
Map fileMap = {};
Future<Map> getSavedEstimates() async {
try {
var savedEstimates = await DirectoryHelper.listOfFiles().then((resp) {
return resp;
});
savedEstimates.forEach((key, value) => print(key));
return savedEstimates;
} catch (e) {
throw Exception("Could Not Retrieve list of saved files");
}
}

Future<List<Widget>> fileListMappedAsWidget() async {
var fileHits =
await getSavedEstimates(); //returns Future<Map<dynamic,dynamic>>
List<Widget> newList = [];
fileHits.forEach((k, v) {
newList.add(Row(
children: [
Text(pathpkg.basename(v)),
BottomButton(
buttonTitle: 'Delete',
onPressed: () => () {
setState(() {
k.deleteSync();
fileMap.remove(k);
});
})
],
));
});
// () => newList;
return newList;
// throw ("f");
}
@override

Widget build(BuildContext context) {
return Container(
child: FutureBuilder(
future: fileListMappedAsWidget(),
// future: testRetrieve,
builder: (BuildContext context, AsyncSnapshot<List> snapshot) {
List<Widget> children;
print(snapshot.connectionState);
if (snapshot.hasData) {
List<Widget> childStuff = [];
for (int i = 0; i < snapshot.data!.length; i++) {
childStuff.add(snapshot.data![i]);
}
children = childStuff;
} else if (snapshot.hasError) {
children = <Widget>[
const Icon(Icons.error_outline, color: Colors.red, size: 60),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Text('Error: ${snapshot.error}'))
];
} else {
children = const <Widget>[
SizedBox(
width: 60, height: 60, child: CircularProgressIndicator()),
Padding(
padding: EdgeInsets.only(top: 16),
child: Text('Awaiting Result'),
)
];
}
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: children,
),
);
}),
);
}
}

file_listing.dart结束

最新更新