Modifier:
Page d'accueil - Je récupère une liste de chaînes de ma collection Firebase. Je veux ensuite appeler le stockage Firestore et obtenir le lien d'image téléchargeable et le stocker dans une liste que je passerai à la page 2. Le code ci-dessous indique comment j'obtiens les liens téléchargeables.
List<T> map<T>(List list, Function handler) {
List<T> result = [];
for (var i = 0; i < list.length; i++) {
result.add(handler(i, list[i]));
}
return result;
}
new CarouselSlider(
items: ***["This is where I need a List"]***.map((url) {
return new Container(
margin: new EdgeInsets.all(5.0),
child:
new GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ViewCarImages(
carImages: _getImages(snapshot))),
);
},
child:
new ClipRRect(
borderRadius: new BorderRadius.all(new Radius.circular(5.0)),
child:
new Image.network(
url,
fit: BoxFit.cover,
width: 1000.0,
)
)
)
);
}).toList(),
viewportFraction: 0.9,
aspectRatio: 2.0,
autoPlay: false,
)
Je passe ensuite la liste des images de la manière suivante
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CarDetailScreen(
carImages: test( car['images'])
)),
);
Page 2 - Je reçois a Future> que je voudrais convertir en liste
Future<List<String>> test(List images) async{
List<String> listOfImages = List<String>();
for(int i = 0; i < images.length; i++){
final ref = FirebaseStorage.instance.ref().child(images[i]);
var url = await ref.getDownloadURL();
listOfImages.add(url);
}
return listOfImages;
}
3 Réponses :
Vous pouvez simplement renvoyer une liste de widgets, comme ceci:
Future<List<Widget>> test(List images) async{
List<Widget> listOfImages = List<Widget>();
for(int i = 0; i < images.length; i++){
final ref = FirebaseStorage.instance.ref().child(images[i]);
var url = await ref.getDownloadURL();
listOfImages.add(Image.network(url));
}
return listOfImages;
}
Le problème est d'appeler cette méthode. C'est un Future > alors que j'ai besoin d'un List
Si votre widget a besoin d'une chaîne de liste au lieu de future, utilisez un futur constructeur et mettez votre widget à l'intérieur. Ajoutez plus de code à votre question
J'ai ajouté du code si cela ne vous dérange pas de jeter un coup d'œil une deuxième fois s'il vous plaît.
Le code ci-dessous résoudra votre problème. Dans la classe carouselSlide (variable de vérification des éléments) écrite ci-dessous et vous devez suivre la procédure ci-dessous pour travailler l'objet Future dans le carrousel
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar: AppBar(
backgroundColor: Colors.white,
title: Text("some text",
style: TextStyle(
fontWeight: FontWeight.normal,
color: Colors.black,
fontSize: 16.0)),
centerTitle: false,
actions: <Widget>[
IconButton(
tooltip: 'Search something',
icon: Icon(
Icons.search,
color: SharedColor().sapphireDarkBlue,
),
onPressed: () async {
var selected = await showSearch<int>(
context: context, delegate: _delegate);
if (selected != null && selected != _lastIntegerSelected) {
setState(() {
//pass the data from searchfield query to here
});
}
},
),
],
automaticallyImplyLeading: false,
),
body: _carouselBuild(),
);
}
FutureBuilder<caraouselImage> _carouselBuild() {
return FutureBuilder<caraouselImage>(
future: ImageRestApiManager().caraouselImage(myEmail),
builder: (context, AsyncSnapshot<caraouselImage> snapshot) {
if (snapshot.hasData) {
return CarouselSlider(
items: snapshot.data.collection.map((i) {
return Builder(builder: (BuildContext context) {
return Container(
margin: EdgeInsets.all(5.0),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(5.0)),
child: Stack(children: <Widget>[
Image.network(i.imageurl,
fit: BoxFit.cover, width: 1000.0),
Positioned(
bottom: 0.0,
left: 0.0,
right: 0.0,
child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Color.fromARGB(200, 0, 0, 0),
Color.fromARGB(0, 0, 0, 0)
],
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
),
),
padding: EdgeInsets.symmetric(
vertical: 10.0, horizontal: 20.0),
child: Text(
_currentCookieSelected.toString(),
style: TextStyle(
color: Colors.white,
fontSize: 20.0,
fontWeight: FontWeight.bold,
),
),
),
),
]),
),
);
});
}).toList(),
autoPlay: false,
enlargeCenterPage: true,
viewportFraction: 0.9,
aspectRatio: 2.0,
onPageChanged: (index) {
setState(() {
_currentImageSelected = snapshot.data.collection[index].id;
});
});
} else {
return CircularProgressIndicator();
}
});
}
}
I solved using below youtube tutorial
https://www.youtube.com/watch?v=xBLtPDHvT44
Un FutureBuilder devrait vous apporter ce que vous recherchez. Ici, j'ai enveloppé votre CarouselSlider dans un FutureBuilder et j'ai défini la future propriété sur votre carImages Future . Lorsque votre liste de chaînes est prête, le FutureBuilder créera le CarouselSlider via sa méthode de générateur, et tous les éléments de la liste seront alors présents:
return FutureBuilder<List<String>>(
future: carImages,
initialData: [],
builder: (context, snapshot) {
return new CarouselSlider(
viewportFraction: 0.9,
aspectRatio: 2.0,
autoPlay: false,
items: snapshot.data.map((url) {
return new Container(
margin: new EdgeInsets.all(5.0),
child:
new GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => ViewCarImages(
carImages: _getImages(snapshot))),
);
},
child: new ClipRRect(
borderRadius: new BorderRadius.all(new Radius.circular(5.0)),
child: new Image.network(
url,
fit: BoxFit.cover,
width: 1000.0,
)
)
)
);
}).toList(),
);
}
);
pourquoi avez-vous besoin de chaîne dynamique à la place?
Parce que j'utilise un plugin (CarouselSlider) et que dans la propriété items, je recherche un List.
Il n'y a aucun moyen de passer de
Futureà un non-futur synchrone. Tout ce que vous faites avec cette valeur doit être asynchrone.FutureBuilderest le moyen typique de flutter - si ce n'est pas possible, vous devrez donner plus de contexte.@NateBosch J'ai ajouté du code à ma question. J'ai essayé d'ajouter un FutureBuilder mais je ne sais vraiment pas comment y parvenir.