Je suis coincé dans mon projet où j'ai deux widgets avec état créés en flutter comme deux fichiers Dart différents. Maintenant, je dois accéder à l'instance d'un objet créé dans le premier widget dans le deuxième widget, mais je ne sais pas trop comment je peux le faire en flottant lors de la création de widgets.
Une solution possible à laquelle j'ai pensé est de déclarer les deux widgets dans un seul fichier Dart au lieu de deux fichiers Dart pour deux dispositions, mais je suis curieux de savoir si nous pouvons le faire en déclarant dans deux fichiers Dart distincts.
J'ai publié les fichiers juste pour recréer le problème.
main.Dart
import 'package:flutter/material.Dart';
import 'package:untitled2/models.Dart';
import 'package:untitled2/secondwidget.Dart';
void main() {
runApp(new MaterialApp(
home: new MyApp(),
),);
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
final TextEditingController _nameController = new TextEditingController();
final TextEditingController _emailIdController = new
TextEditingController();
final TextEditingController _passwordController = new
TextEditingController();
final TextEditingController _confirmPasswordController = new
TextEditingController();
MyModel myModel = new MyModel();
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
body: new ListView(
children: <Widget>[
new Container(
child: new TextFormField(
decoration: new InputDecoration(
labelText: 'Enter your Name'
),
controller: _nameController,
onSaved: (String value){myModel.name = value;} ,
),
),
new Container(
child: new TextFormField(
decoration: new InputDecoration(
labelText: 'EmailId'
),
controller: _emailIdController,
onSaved: (String value){myModel.emailId = value;}
),
),
new Container(
child: new TextFormField(
decoration: new InputDecoration(
labelText: 'Password'
),
controller: _passwordController,
onSaved: (String value){myModel.password = value;}
),
),
new Container(
child: new TextFormField(
decoration: new InputDecoration(
labelText: 'Confirm Password'
),
controller: _confirmPasswordController,
),
),
new Container(
child: new FlatButton(
onPressed: ((){
Navigator.Push(context, new MaterialPageRoute(builder: (_) =>
new SecondScreen(),),);
}),
child: new Text('Save'),),
),
],
),
),
);
}
}
models.Dart
class MyModel {
String name;
String emailId;
String password;
}
secondwidget.Dart
import 'package:flutter/material.Dart';
class SecondScreen extends StatefulWidget {
@override
_SecondScreenState createState() => new _SecondScreenState();
}
class _SecondScreenState extends State<SecondScreen> {
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
body: new ListView(
children: <Widget>[
new Container(
child: new TextFormField(
decoration: new InputDecoration(
labelText: 'Enter address'
),
),
),
new Container(
child: new TextFormField(
decoration: new InputDecoration(
labelText: 'Address Line 2'
),
),
),
new Container(
child: new TextFormField(
decoration: new InputDecoration(
labelText: 'Address Line 3'
),
),
),
new Container(
child: new TextFormField(
decoration: new InputDecoration(
labelText: 'POST CODE'
),
),
),
new Container(
child: new TextFormField(
decoration: new InputDecoration(
labelText: 'Mobile Number'
),
),
),
new Container(
child: new FlatButton(
onPressed: ((){
//I want to Push the data captured from main.Dart and from
//secondwidget.Dart into database
// I want to use the instance of MyModel from main.Dart here to save
// the data captured from the first screen and this one into database
}),
child: new Text('Save'),),
),
],
),
),
);
}
}
Il existe de nombreuses façons de procéder en fonction de votre cas d'utilisation. Voici quelques options:
State
. Utilisez ensuite la propriété currentState
d'un GlobalKey
dans un State
pour obtenir une référence à l'autre State
. Vous pouvez maintenant accéder à l'objet créé via le membre public. (Remarque: ce modèle limite la testabilité et l'encapsulation de votre State
, alors utilisez-le avec parcimonie.)InheritedWidget
qu'ils utilisent pour rechercher l'objet créé.ValueNotifier
. Ils peuvent utiliser cet objet pour lire et écrire la valeur.Si vous allez plus en détail sur votre cas d'utilisation, nous pouvons vous aider à choisir un modèle qui a du sens.
Voici quelques options d'implémentation de code # 1.
import 'package:flutter/material.Dart';
void main() {
runApp(new MyApp());
}
final key = new GlobalKey<MyStatefulWidget1State>();
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
body: new Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
new MyStatefulWidget1(key: key),
new MyStatefulWidget2(),
],
),
),
);
}
}
class MyStatefulWidget1 extends StatefulWidget {
MyStatefulWidget1({ Key key }) : super(key: key);
State createState() => new MyStatefulWidget1State();
}
class MyStatefulWidget1State extends State<MyStatefulWidget1> {
String _createdObject = "Hello world!";
String get createdObject => _createdObject;
@override
Widget build(BuildContext context) {
return new Center(
child: new Text(_createdObject),
);
}
}
class MyStatefulWidget2 extends StatefulWidget {
State createState() => new MyStatefulWidget2State();
}
class MyStatefulWidget2State extends State<MyStatefulWidget2> {
String _text = 'PRESS ME';
@override
Widget build(BuildContext context) {
return new Center(
child: new RaisedButton(
child: new Text(_text),
onPressed: () {
setState(() {
_text = key.currentState.createdObject;
});
},
),
);
}
}
Vous pouvez transmettre le modèle lorsque vous construisez le widget SecondScreen
.
Ajouter un modèle au constructeur SecondScreen
:
class SecondScreen extends StatefulWidget {
final MyModel myModel;
SecondScreen(MyModel myModel, {Key key}):
super(key: key);
...
}
Passez le modèle lorsque vous construisez SecondScreen
dans main.Dart
Navigator.Push(context, new MaterialPageRoute(builder: (_) =>
new SecondScreen(model)));
Vous pouvez maintenant accéder au modèle dans _SecondScreenState
via widget.myModel