Nous avons créé une application Flutter qui affiche une liste à partir d'une liste d'éléments. Nous voulons pouvoir les mettre à jour en fonction des préférences de l'utilisateur. Un peu comme si vous aviez une liste de choses à faire et que vous vouliez corriger ou mettre à jour l'un des éléments de la liste à l'aide d'un modal ou d'une boîte de dialogue.
J'ai essayé de mettre à jour un seul élément dans la liste avec une boîte de dialogue sur laquelle l'utilisateur tape, puis se ferme lors de l'envoi. Jusqu'à présent, je n'ai pas eu de chance, mais je me sens très proche. Comment puis-je mettre le nom sur la vignette à jour lors de la soumission et rendre à nouveau la page? Que me manque-t-il?
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { List<Animal> animals = new List(); String newName; TextEditingController nctrl = TextEditingController(); @override void initState() { super.initState(); animals = [ Animal(id: 1, name: 'cat'), Animal(id: 2, name: 'dog'), Animal(id: 3, name: 'mouse'), Animal(id: 4, name: 'horse'), Animal(id: 5, name: 'frog'), ]; } _changePetName() { newName = nctrl.text; Navigator.pop(context); return newName; } _showDialog(String name) { nctrl.text = name; showDialog( context: context, builder: (BuildContext context) { // return object of type Dialog return AlertDialog( elevation: 5, backgroundColor: Colors.blue, title: Text( "Rename this pet", ), content: Container( child: Column( mainAxisSize: MainAxisSize.min, children: <Widget>[ TextField( controller: nctrl, onChanged: (e) { setState(() {}); }, ), ], )), actions: <Widget>[ // usually buttons at the bottom of the dialog FlatButton( child: Text("Close"), onPressed: () { Navigator.of(context).pop(); }, ), FlatButton( color: Colors.green, child: Text( "Submit", ), onPressed: () { var updateName = _changePetName(); return updateName; }, ), ], ); }, ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ ListView.builder( scrollDirection: Axis.vertical, shrinkWrap: true, itemCount: animals.length, itemBuilder: (BuildContext context, int index) { var pet = animals[index]; return ListTile( key: ValueKey(pet.id), enabled: true, onTap: () async { var rename = await _showDialog(pet.name); if (rename != null) { pet.name = rename; setState(() {}); } // setState(() { // pet.name = 'bob'; // }); }, title: Text(pet.name), ); }, ), ], ), ), ); } } class Animal { final int id; String name; Animal({this.id, this.name}); factory Animal.fromJson(Map<dynamic, dynamic> json) { return new Animal( id: json['id'], name: json['name'], ); } Map<dynamic, dynamic> toJson() { final Map<dynamic, dynamic> data = new Map<dynamic, dynamic>(); data['id'] = this.id; data['name'] = this.name; return data; } }
3 Réponses :
Dans la boîte de dialogue Méthode d'alerte Onpress, collez simplement ce code
Navigator.pushReplacement( context, MaterialPageRoute(builder: (_) => MyHomePage()));
Nous dirigerons votre page vers la même chose.
Merci @Rutvik Gumasana pour votre aide. Cette solution ne fonctionnerait pas pour moi car j'ai d'autres données qui seraient effacées si je pousseReplacement. La solution ci-dessus a bien fonctionné, au cas où vous seriez intéressé.
Quelques corrections qui feront fonctionner votre code:
Voici le code de travail pour votre référence:
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { List<Animal> animals = new List(); String newName; TextEditingController nctrl = TextEditingController(); @override void initState() { super.initState(); animals = [ Animal(id: 1, name: 'cat'), Animal(id: 2, name: 'dog'), Animal(id: 3, name: 'mouse'), Animal(id: 4, name: 'horse'), Animal(id: 5, name: 'frog'), ]; } _changePetName() { newName = nctrl.text; Navigator.pop(context, newName); return newName; } Future<String> _showDialog(String name) async { nctrl.text = name; return await showDialog<String>( context: context, builder: (BuildContext context) { // return object of type Dialog return AlertDialog( elevation: 5, backgroundColor: Colors.blue, title: Text( "Rename this pet", ), content: Container( child: Column( mainAxisSize: MainAxisSize.min, children: <Widget>[ TextField( controller: nctrl, onChanged: (e) { // setState(() {}); }, ), ], )), actions: <Widget>[ // usually buttons at the bottom of the dialog FlatButton( child: Text("Close"), onPressed: () { Navigator.of(context).pop(nctrl.text); }, ), FlatButton( color: Colors.green, child: Text( "Submit", ), onPressed: () { var updateName = _changePetName(); return updateName; }, ), ], ); }, ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ ListView.builder( scrollDirection: Axis.vertical, shrinkWrap: true, itemCount: animals.length, itemBuilder: (BuildContext context, int index) { var pet = animals[index]; return ListTile( key: ValueKey(pet.id), enabled: true, onTap: () async { var rename = await _showDialog(pet.name); if (rename != null) { pet.name = rename; setState(() {}); } // setState(() { // pet.name = 'bob'; // }); }, title: Text(pet.name), ); }, ), ], ), ), ); } } class Animal { final int id; String name; Animal({this.id, this.name}); factory Animal.fromJson(Map<dynamic, dynamic> json) { return new Animal( id: json['id'], name: json['name'], ); } Map<dynamic, dynamic> toJson() { final Map<dynamic, dynamic> data = new Map<dynamic, dynamic>(); data['id'] = this.id; data['name'] = this.name; return data; } }
Si cette solution fonctionne pour vous, veuillez accepter et voter la réponse.
Merci @Kalpesh Kundanani, cette solution a fonctionné comme nous le voulions. Merci pour l'aide!
C'est génial... :)
essayez ceci,
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { List<Animal> animals = new List(); String newName; TextEditingController nctrl = TextEditingController(); @override void initState() { super.initState(); animals = [ Animal(id: 1, name: 'cat'), Animal(id: 2, name: 'dog'), Animal(id: 3, name: 'mouse'), Animal(id: 4, name: 'horse'), Animal(id: 5, name: 'frog'), ]; } _showDialog(int index) { nctrl.text = animals[index].name; showDialog( context: context, builder: (BuildContext context) { // return object of type Dialog return AlertDialog( elevation: 5, backgroundColor: Colors.blue, title: Text( "Rename this pet", ), content: Container( child: Column( mainAxisSize: MainAxisSize.min, children: <Widget>[ TextField( controller: nctrl, onChanged: (e) { setState(() {}); }, ), ], )), actions: <Widget>[ // usually buttons at the bottom of the dialog FlatButton( child: Text("Close"), onPressed: () { Navigator.of(context).pop(); }, ), FlatButton( color: Colors.green, child: Text( "Submit", ), onPressed: () { setState(() { animals[index].name = nctrl.text; }); Navigator.pop(context); }, ), ], ); }, ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ ListView.builder( scrollDirection: Axis.vertical, shrinkWrap: true, itemCount: animals.length, itemBuilder: (BuildContext context, int index) { var pet = animals[index]; return ListTile( key: ValueKey(pet.id), enabled: true, onTap: () async { var rename = await _showDialog(index); if (rename != null) { animals[index].name = rename; setState(() {}); } // setState(() { // pet.name = 'bob'; // }); }, title: Text(pet.name), ); }, ), ], ), ), ); } } class Animal { final int id; String name; Animal({this.id, this.name}); factory Animal.fromJson(Map<dynamic, dynamic> json) { return new Animal( id: json['id'], name: json['name'], ); } Map<dynamic, dynamic> toJson() { final Map<dynamic, dynamic> data = new Map<dynamic, dynamic>(); data['id'] = this.id; data['name'] = this.name; return data; } }
Merci pour votre aide @Nardeppsinh Vaghela. Cette solution fonctionne bien.