目前我有这个功能:
Future<void> savePictureToLocalStorage() async {
// Obtenez le répertoire des documents de l'application
Directory appDocDir = await getApplicationDocumentsDirectory();
// Créez un fichier avec le nom de fichier souhaité dans le répertoire des documents de l'application
File targetFile = File('${appDocDir.path}/$_imageFile');
// Copiez le fichier source dans le fichier cible
await _imageFile!.copy(targetFile.path);
profile.profilePicture = targetFile.path;
}
我把它叫做:
void saveAll(BuildContext context) async {
String pseudo = nameController.text.trim();
if (pseudo == "") {
_showPopup(context);
}
if (imageChanged) {
await savePictureToLocalStorage();
await deleteImageIfLinkExists();
await updateImageFirebase();
}
if (nameController.text != profile.nickname) {
profile.nickname = nameController.text;
updateNameFirebase();
}
await UserProfile.saveProfileIntoMemory();
}
我希望savePictureToLocalStorage()在saveAll函数结束之前完成。
然而事实并非如此。其他函数只是在savePictureToLocalStorage()完成之前继续运行。
对于上下文:
我有阶级联系
import 'dart:io';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:jukebox/screens/update_account_case.dart';
import 'package:jukebox/utils/ElevatedButtonImpl.dart';
import '../backend/music_platform.dart';
import '../backend/user_profile.dart';
import '../utils/globals.dart' as globals;
class Connexion extends StatefulWidget {
const Connexion({super.key});
@override
State<Connexion> createState() => ConnexionState();
}
class ConnexionState extends State<Connexion> {
final textController = TextEditingController();
Image? _profilePicture;
ConnexionState() {
_init();
}
/// This function is used to initialize the user profile
Future _init() async {
final UserProfile profile = UserProfile.instance;
textController.text = profile.nickname;
_profilePicture = profile.profilePicture == 'default'
? Image.asset('images/default_profile_picture.png')
: Image.asset(profile.profilePicture);
DocumentSnapshot userSnapshot = await FirebaseFirestore.instance
.collection('User')
.doc(profile.userId)
.get();
if (!userSnapshot.exists) {
createUserFirebase(profile);
}
}
createUserFirebase(UserProfile userProfile) async {
var collection = FirebaseFirestore.instance.collection('User');
collection.doc(userProfile.userId).set({
'name': userProfile.nickname,
'profile_picture': userProfile.profilePicture,
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
extendBody: true,
resizeToAvoidBottomInset: true,
extendBodyBehindAppBar: true,
bottomNavigationBar: ElevatedButtonImpl(
onPressed: () async {
await Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) {
return UpdateAccountInfo(profilePicture: _profilePicture);
},
fullscreenDialog: true,
));
setState(() {
textController.text = UserProfile.instance.nickname;
_profilePicture = UserProfile.instance.profilePicture == 'default'
? Image.asset(globals.defaultPicture)
: Image.asset(UserProfile.instance.profilePicture);
});
},
text: "Modifier",
),
body: Container(
height: double.infinity,
width: double.infinity,
decoration: const BoxDecoration(
gradient: LinearGradient(
begin: Alignment.bottomLeft,
end: Alignment.topRight,
colors: [
Color.fromRGBO(125, 70, 151, 1),
Color.fromRGBO(255, 0, 157, 1),
],
),
),
child: Center(
child: SizedBox(
width: 350,
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
_profilePicture == null
? const CircleAvatar(
radius: 120,
backgroundImage: AssetImage('images/camera.png'),
)
: CircleAvatar(
radius: 120,
backgroundImage: _profilePicture!.image,
),
TextField(
controller: textController,
autofocus: false,
scrollPadding: const EdgeInsets.only(bottom: 300),
cursorColor: const Color.fromRGBO(233, 165, 208, 1),
maxLength: 15,
textAlign: TextAlign.center,
style: const TextStyle(
color: Color.fromRGBO(233, 165, 208, 0.9), fontSize: 40),
decoration: const InputDecoration(counterText: ""),
readOnly: true,
),
//PLATFORMS
for (var platform in MusicPlatform.values)
PlatformButton(musicPlatform: platform),
],
),
),
),
),
);
}
}
class PlatformButton extends StatelessWidget {
final MusicPlatform musicPlatform;
const PlatformButton({Key? key, required this.musicPlatform})
: super(key: key);
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.only(bottom: 10, right: 0, top: 10, left: 0),
child: ElevatedButton(
style: ButtonStyle(
padding: const MaterialStatePropertyAll(EdgeInsets.all(0)),
shape: MaterialStatePropertyAll(
RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
),
),
onPressed: () {},
child: Row(
children: [
// ignore: sized_box_for_whitespace
Container(
height: 40,
width: 39,
child: const Card(
color: Colors.blue,
),
),
const SizedBox(
width: 10,
),
Text(
musicPlatform.platformName,
style: const TextStyle(
color: Color.fromRGBO(255, 0, 157, 1),
),
),
const Expanded(
child: Card(),
),
IconButton(
iconSize: 40,
onPressed: () {},
icon: const Icon(
Icons.check_outlined,
color: Color.fromRGBO(255, 0, 157, 1),
),
)
],
),
),
);
}
}
在小部件ElevatedButtonImpl的onPressed属性中,我调用类UpdateAccountInfo。
它调用下面的UpdateAccountInfo类:
import 'dart:io';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
import 'package:jukebox/utils/ContainerImpl.dart';
import 'package:jukebox/utils/ElevatedButtonImpl.dart';
import 'package:path_provider/path_provider.dart';
import '../backend/user_profile.dart';
import 'package:path/path.dart';
import '../utils/globals.dart' as globals;
class UpdateAccountInfo extends StatefulWidget {
final Image? profilePicture;
const UpdateAccountInfo({Key? key, required this.profilePicture})
: super(key: key);
@override
State<UpdateAccountInfo> createState() => _UpdateAccountInfo();
}
class _UpdateAccountInfo extends State<UpdateAccountInfo> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text(globals.majInfo),
backgroundColor: const Color.fromRGBO(255, 0, 157, 1),
),
body: Center(
child: Form(profilePicture: widget.profilePicture),
),
);
}
}
class Form extends StatefulWidget {
Image? profilePicture;
Form({Key? key, required this.profilePicture}) : super(key: key);
@override
State<Form> createState() => _Form();
}
class _Form extends State<Form> {
File? _imageFile;
final FirebaseStorage _storage = FirebaseStorage.instance;
final nameController = TextEditingController();
final UserProfile profile = UserProfile.instance;
bool imageChanged = false;
bool nameChanged = false;
_Form() {
_init();
}
Future _init() async {
final UserProfile profile = UserProfile.instance;
nameController.text = profile.nickname;
}
Future _pickImage(ImageSource source) async {
try {
final image = await ImagePicker().pickImage(source: source);
if (image == null) return;
_imageFile = File(image.path);
setState(() {
widget.profilePicture = Image.file(_imageFile!);
});
} on Exception catch (e) {
// ignore: avoid_print
print(e);
Navigator.of(context as BuildContext).pop();
}
}
Future<void> deleteImageIfLinkExists() async {
// Récupérer le lien actuel depuis la table
FirebaseFirestore firestore = FirebaseFirestore.instance;
DocumentSnapshot userSnapshot =
await firestore.collection('User').doc(profile.userId).get();
Map<String, dynamic> userData = userSnapshot.data() as Map<String, dynamic>;
String profilePicture = userData['profile_picture'];
// Vérifier si le lien est non null et non vide
if (profilePicture != 'default') {
// Créer une référence au fichier dans Firebase Storage
Reference ref = FirebaseStorage.instance.refFromURL(profilePicture);
// Supprimer le fichier du Firebase Storage
try {
await ref.delete();
} catch (e) {
// Gérer les erreurs de suppression de fichier ici
}
}
}
@override
Widget build(BuildContext context) {
return ContainerImpl(
child: SingleChildScrollView(
child: Column(
children: [
const SizedBox(
height: 20,
),
const SizedBox(
height: 20,
),
CircleAvatar(
radius: 120,
backgroundImage: widget.profilePicture!.image,
),
const SizedBox(
height: 20,
),
ElevatedButtonImpl(
onPressed: () {
_pickImage(ImageSource.gallery);
imageChanged = true;
},
text: "Importer une photo"),
const SizedBox(
height: 20,
),
TextField(
controller: nameController,
autofocus: false,
scrollPadding: const EdgeInsets.only(bottom: 300),
cursorColor: const Color.fromRGBO(233, 165, 208, 1),
maxLength: 15,
textAlign: TextAlign.center,
style: const TextStyle(
color: Color.fromRGBO(233, 165, 208, 0.9), fontSize: 40),
decoration: const InputDecoration(counterText: ""),
),
const SizedBox(
height: 80,
),
Row(
children: [
Expanded(
child: ElevatedButtonImpl(
onPressed: () {
saveAll(context);
Navigator.pop(context);
},
text: "Enregistrer"))
],
)
],
),
));
}
void _showPopup(BuildContext context) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('Pseudo vide'),
content: const Text('Veuillez renseigner un pseudo'),
actions: <Widget>[
TextButton(
child: const Text('OK'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
void saveAll(BuildContext context) async {
String pseudo = nameController.text.trim();
if (pseudo == "") {
_showPopup(context);
}
if (imageChanged) {
await savePictureToLocalStorage();
await deleteImageIfLinkExists();
await updateImageFirebase();
}
if (nameController.text != profile.nickname) {
profile.nickname = nameController.text;
updateNameFirebase();
}
await UserProfile.saveProfileIntoMemory();
}
Future<void> updateImageFirebase() async {
String profilePicture = profile.profilePicture;
Reference ref = _storage.ref("profile_pictures");
UploadTask uploadTask = ref.putFile(_imageFile!);
// Attendez la fin de l'UploadTask
TaskSnapshot snapshot = await uploadTask;
// Récupérez l'URL de téléchargement
profilePicture = await snapshot.ref.getDownloadURL();
// Mettez à jour la base de données
var collection = FirebaseFirestore.instance.collection('User');
await collection
.doc(profile.userId)
.update({'profile_picture': profilePicture, 'name': profile.nickname});
// Mettez à jour l'objet profile
profile.profilePicture = profilePicture;
}
void updateNameFirebase() {
var collection = FirebaseFirestore.instance.collection('User');
collection.doc(profile.userId).update({'name': nameController.text});
}
Future<void> savePictureToLocalStorage() async {
// Obtenez le répertoire des documents de l'application
Directory appDocDir = await getApplicationDocumentsDirectory();
// Créez un fichier avec le nom de fichier souhaité dans le répertoire des documents de l'application
File targetFile = File('${appDocDir.path}/$_imageFile');
// Copiez le fichier source dans le fichier cible
await _imageFile!.copy(targetFile.path);
profile.profilePicture = targetFile.path;
}
}
如果你发现了窍门,提前谢谢你。
我试着把等待几乎无处不在。
1条答案
按热度按时间eqqqjvef1#
将void函数转换为
Future<void>
等着完成它。