我有个问题。
因此,我尝试将多张图片上传到Firebase存储中,这些图片通过MultiImage选择器进入手机内存,该选择器仅将数据保存到列表中
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:multi_image_picker2/multi_image_picker2.dart';
import 'package:provider/provider.dart';
import '../widgets/bottom_navigation_bar.dart';
import '../providers/selling.dart';
//Property Features Screens
import '../screens/land_lot_size_features.dart';
import '../screens/condo_property_details_features.dart';
import '../screens/townhose_property_detais_features.dart';
import '../screens/home_property_details_features.dart';
import '../screens/selling_bathrooms.dart';
//Next Page Pricing
import '../screens/pricing_property.dart';
class MultipleImageDemo extends StatefulWidget {
static const routeName = '/multi-picker';
@override
_MultipleImageDemoState createState() => _MultipleImageDemoState();
}
class _MultipleImageDemoState extends State<MultipleImageDemo> {
List<Asset> images = <Asset>[];
double screenWidth = 0;
bool isLoading = false;
@override
void initState() {
setState(() {
isLoading = true;
});
images = Provider.of<Selling>(context, listen: false).images;
setState(() {
isLoading = true;
});
super.initState();
}
Future<void> loadAssets() async {
List<Asset> resultList = <Asset>[];
try {
resultList = await MultiImagePicker.pickImages(
maxImages: 12,
enableCamera: true,
selectedAssets: images,
cupertinoOptions: CupertinoOptions(takePhotoIcon: "chat"),
materialOptions: MaterialOptions(
actionBarColor: "#abcdef",
actionBarTitle: "Roof Deck",
allViewTitle: "All Photos",
useDetailsView: false,
selectCircleStrokeColor: "#000000",
),
);
} on Exception catch (e) {
//String error = e.toString();
print(e);
}
if (!mounted) return;
setState(() {
images = resultList;
});
}
deleteImage(index) {
images.removeAt(index);
setState(() {});
}
@override
Widget build(BuildContext context) {
final topData = Provider.of<Selling>(context);
final typeOfProperty = topData.menu;
screenWidth = MediaQuery.of(context).size.width;
return Scaffold(
body: SafeArea(
child: Stack(
children: [
// SizedBox(
// height: 1,
// ),
// Positioned(
// top: 0,
// left: 0,
// right: 0,
// child: Container(
// width: screenWidth,
// padding: const EdgeInsets.all(15),
// margin: const EdgeInsets.all(15),
// child: LinearPercentIndicator(
// width: screenWidth / 1.2,
// lineHeight: 8.0,
// percent: 0.50,
// progressColor: Colors.deepPurple[900],
// ),
// ),
// ),
Container(
// width: screenWidth,
// padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 5),
// margin: const EdgeInsets.symmetric(horizontal: 15, vertical: 5),
child: CustomScrollView(
slivers: [
SliverToBoxAdapter(
child: Container(
// padding: const EdgeInsets.only(
// top: 5,
// left: 15,
// right: 15,
// ),
// margin: const EdgeInsets.only(
// top: 5,
// left: 15,
// right: 15,
// ),
child: Column(
children: [
Center(
child: Text(
'Photos',
style: TextStyle(fontSize: 25),
),
),
Divider(
color: Colors.grey,
thickness: 2.00,
),
SizedBox(
height: 5,
),
],
),
),
),
// SliverToBoxAdapter(
// child: Padding(
// padding: const EdgeInsets.only(
// left: 15.0, right: 15.0, bottom: 5.0),
// child: Text(
// 'Homes are 30% more likely to sell with high quality photos.',
// style: TextStyle(
// color: Colors.grey,
// fontSize: 18.00,
// ),
// ),
// ),
// ),
// SliverToBoxAdapter(
// child: Padding(
// padding: const EdgeInsets.only(
// left: 15.0, right: 15.0, bottom: 20.0),
// child: Text(
// 'You can only upload 12 pictures, if you need to remove a picture just tap on it.',
// style: TextStyle(
// color: Colors.grey,
// fontSize: 18.00,
// ),
// ),
// ),
// ),
SliverPadding(
padding: const EdgeInsets.symmetric(
horizontal: 15,
),
sliver: SliverGrid(
delegate: SliverChildBuilderDelegate(
(BuildContext context, int index) {
return index == images.length
? Center(
child: DecoratedBox(
decoration: BoxDecoration(
color: Colors.grey,
borderRadius: BorderRadius.circular(5),
border: Border.all(
color: Colors.grey, width: 1.0),
),
child: Container(
margin: const EdgeInsets.all(16.0),
padding: const EdgeInsets.all(8.0),
height: 100,
width: 100,
child: IconButton(
icon: Icon(
Icons.add, //add_a_photo,
size: 50.00,
color: Colors.white,
),
onPressed: () {
if (images.length < 12) {
loadAssets();
} else {
showDialog(
context: context,
builder: (ctx) => AlertDialog(
title: Text(
'Max Number of Pictures'),
content: Text(
'You reached the maximum number of pictures that can be uploaded (12 pictures)'),
actions: [
TextButton(
child: Text('Okay'),
onPressed: () {
Navigator.of(ctx).pop();
},
),
],
),
);
}
},
),
),
),
)
: GestureDetector(
onTap: () {
deleteImage(index);
},
child: Container(
margin: const EdgeInsets.all(3),
decoration: BoxDecoration(
border: Border.all(
color: Colors.grey, width: 1.0),
borderRadius: BorderRadius.all(
Radius.circular(5.0),
),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(4.0),
child: AssetThumb(
asset: images[index],
width: 300,
height: 300,
),
),
),
);
},
childCount: images.length + 1,
),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
),
),
),
],
),
),
Positioned(
bottom: 0,
left: 0,
right: 0,
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 15,
),
color: Colors.white,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
TextButton(
child: Text(
'Previous',
style: TextStyle(fontSize: 22),
),
onPressed: () {
switch (typeOfProperty) {
case 0:
{
Navigator.pushNamed(
context, PropertyBathrooms.routeName);
}
break;
case 1:
{
Navigator.push(
context,
PageRouteBuilder(
transitionDuration: Duration(seconds: 0),
pageBuilder: (_, __, ___) =>
LandSizeFeatures()),
);
}
break;
case 2:
{
Navigator.push(
context,
PageRouteBuilder(
transitionDuration: Duration(seconds: 0),
pageBuilder: (_, __, ___) =>
TownhousePropertyDetails()),
);
}
break;
case 3:
{
Navigator.push(
context,
PageRouteBuilder(
transitionDuration: Duration(seconds: 0),
pageBuilder: (_, __, ___) =>
CondoPropertyDetails()),
);
}
break;
case 4:
{
Navigator.push(
context,
PageRouteBuilder(
transitionDuration: Duration(seconds: 0),
pageBuilder: (_, __, ___) =>
HomePropertyDetails()),
);
}
break;
}
// Navigator.pushNamed(
// context, PropertyBathrooms.routeName);
},
),
TextButton(
child: Text(
'Next',
style: TextStyle(fontSize: 22),
),
onPressed: () {
Provider.of<Selling>(context, listen: false)
.getImages(images);
Navigator.push(
context,
PageRouteBuilder(
transitionDuration: Duration(seconds: 0),
pageBuilder: (_, __, ___) => PricingProperty()),
);
//Navigator.pushNamed(context, PropertySize.routeName);
},
),
],
),
),
),
],
),
),
bottomNavigationBar: BottomNavBar(2),
);
}
}
一旦我们移动到不同的屏幕,我将该列表保存到提供商,以便在任何地方都可以使用:
//***Property Images***/
List<Asset> _images = <Asset>[];
//Images Getter
List<Asset> get images {
return _images;
}
//Filling the Data Function
void getImages(List<Asset> images) {
_images = images;
notifyListeners();
}
//*** END OF IMAGES ***//
上面的代码是我如何在图像提供程序中填充图像。
现在所有这些工作,但是问题是,现在我希望将该列表中的所有图像上传到Firebase存储,并使用图片查看URL(DownloadURL)取回字符串列表。
我可以通过在1乘1的情况下执行此操作并发送一个文件而不是资产列表来做到这一点,例如以下代码:
final ref = FirebaseStorage.instance
.ref()
.child('user_images')
.child(authResult.user.uid + '.jpg');
await ref.putFile(image);
final url = await ref.getDownloadURL();
但是有没有办法一次完成这一切,而不是1乘1,并检索下载URL的字符串列表?
我的最终目标是能够将这些图像存储在Firebase存储中,并将这些图像的url数组保存到FiRecovery。
在我的简历中,我的问题是我没有上传文件或文件列表,而是上传了资产列表,它是一个列表,而不是一个列表。
谢谢你和亲切的问候。
如果有人来这里寻求答案,我找到了:
我添加了包flutter_absolute_path:^1.0.6,得到了以下代码:
resultList.forEach((imageAsset) async {
final filePath =
await FlutterAbsolutePath.getAbsolutePath(imageAsset.identifier);
File tempFile = File(filePath);
if (tempFile.existsSync()) {
fileImageArray.add(tempFile);
}
});
有了它,我将文件数组保存到我的提供商。然后我创建了一个函数来执行上传到Firebase存储:
Future<void> uploadImages(String id) async {
int i = 0;
for (File imageFile in imageFiles) {
try {
var ref = FirebaseStorage.instance
.ref()
.child('ListingImages')
.child(id)
.child(i.toString() + '.jpg');
await ref.putFile(imageFile);
var url = await ref.getDownloadURL();
_imagesUrl.add(url);
i++;
} catch (err) {
print(err);
}
}
notifyListeners();
print(_imagesUrl);
}
允许我遍历上传的每个文件并将下载URL保存在字符串数组中。
希望这对你们有帮助,伙计们。