【发布时间】:2021-08-17 18:09:52
【问题描述】:
我正在尝试显示不同图像的水平可滚动 ListView。这应该通过 Widget MultipleImageDemo 来实现。我在 loadAssets() 中使用 MultipleImagePicker 来创建从 iPhone 库中选择的图像的资产列表。然后,我将这些资产转换为文件,以便我可以使用来自How to convert asset image to File? 的 getImageFileFromAssets(Asset asset) 在 ListView 中显示它们。但是,将资产转换为文件的函数是异步的,因此当我尝试在 Widget 构建(BuildContext 上下文)中使用此函数时,我需要使用 FutureBuilder。
这就是我尝试实现它的方式:
Future<File> getImageFileFromAssets(Asset asset) async {
final byteData = await asset.getByteData();
final tempFile =
File("${(await getTemporaryDirectory()).path}/${asset.name}");
final file = await tempFile.writeAsBytes(
byteData.buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes),
);
class MultipleImageDemo extends StatefulWidget {
@override
_MultipleImageDemoState createState() => _MultipleImageDemoState();
}
class _MultipleImageDemoState extends State<MultipleImageDemo> {
List<Asset> images = <Asset>[];
@override
void initState() {
super.initState();
}
Future<ListView> DisplayPhotos() async {
List<File> displayedPhotos = <File>[];
for (var i = 0; i < images.length; i++) {
File image_file = await getImageFileFromAssets(images[i]);
displayedPhotos.add(image_file);
}
return ListView(
scrollDirection: Axis.horizontal,
children: List.generate(displayedPhotos.length, (index) {
File displayedPhoto = displayedPhotos[index];
return Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Image.file(displayedPhoto));
}));
}
Future<void> loadAssets() async {
List<Asset> resultList = <Asset>[];
String error = 'No Error Detected';
try {
resultList = await MultiImagePicker.pickImages(
maxImages: 300,
enableCamera: true,
selectedAssets: images,
cupertinoOptions: CupertinoOptions(takePhotoIcon: "chat"),
materialOptions: MaterialOptions(
actionBarColor: "#abcdef",
actionBarTitle: "Example App",
allViewTitle: "All Photos",
useDetailsView: false,
selectCircleStrokeColor: "#000000",
),
);
} on Exception catch (e) {
error = e.toString();
}
if (!mounted) return;
setState(() {
images = resultList;
// _error = error;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
child: Text("Pick images"),
onPressed: loadAssets,
),
Expanded(
child: FutureBuilder<ListView>(
future: DisplayPhotos(),
builder: (BuildContext context,
AsyncSnapshot<ListView> snapshot) {
List<Widget> children;
if (snapshot.hasData) {
children = <Widget>[
const Icon(
Icons.check_circle_outline,
color: Colors.green,
size: 60,
),
Padding(
padding: const EdgeInsets.only(top: 16),
child: Text('Result: ${snapshot.data}'),
)
];
}
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: children,
),
);
})),
],
),
),
);
}
}
这是我得到的错误:
The following assertion was thrown building FutureBuilder<ListView>(dirty, state: _FutureBuilderState<ListView>#66af4):
'package:flutter/src/widgets/framework.dart': Failed assertion: line 1741 pos 14: 'children != null': is not true.
2
Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
https://github.com/flutter/flutter/issues/new?template=2_bug.md
The relevant error-causing widget was
FutureBuilder<ListView>
package:project_startup/screens/addPage.dart:279
When the exception was thrown, this was the stack
#2 new MultiChildRenderObjectWidget
package:flutter/…/widgets/framework.dart:1741
#3 new Flex
package:flutter/…/widgets/basic.dart:4371
#4 new Column
package:flutter/…/widgets/basic.dart:4939
#5 _MultipleImageDemoState.build.<anonymous closure>
package:project_startup/screens/addPage.dart:323
#6 _FutureBuilderState.build
package:flutter/…/widgets/async.dart:775
如何正确实现 FutureBuilder?有必要用吗?
【问题讨论】:
标签: flutter dart listview assets flutter-futurebuilder