Ответ 1
Этот ответ будет охватывать как передачу данных вперед, так и передачу данных обратно. В отличие от Android Activity и iOS ViewControllers, разные экраны во Flutter являются просто виджетами. Навигация между ними включает создание чего-либо, называемого маршрутом, и использование Navigator
для проталкивания и извлечения маршрутов из стека.
Передача данных вперед на следующий экран
Чтобы отправить данные на следующий экран, вы делаете следующие вещи:
-
Сделайте так,
SecondScreen
конструкторSecondScreen
принял параметр для типа данных, которые вы хотите отправить ему. В этом конкретном примере данные определены какString
значения и задаются здесь с помощьюthis.text
.class SecondScreen extends StatelessWidget { final String text; SecondScreen({Key key, @required this.text}) : super(key: key); ...
-
Затем с помощью
Navigator
в виджетеFirstScreen
маршрут к виджетуSecondScreen
. Вы помещаете данные, которые хотите отправить, в качестве параметра в его конструктор.Navigator.push( context, MaterialPageRoute( builder: (context) => SecondScreen(text: 'Hello',), ));
Полный код для main.dart
находится здесь:
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
title: 'Flutter',
home: FirstScreen(),
));
}
class FirstScreen extends StatefulWidget {
@override
_FirstScreenState createState() {
return _FirstScreenState();
}
}
class _FirstScreenState extends State<FirstScreen> {
// this allows us to access the TextField text
TextEditingController textFieldController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('First screen')),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(32.0),
child: TextField(
controller: textFieldController,
style: TextStyle(
fontSize: 24,
color: Colors.black,
),
),
),
RaisedButton(
child: Text(
'Go to second screen',
style: TextStyle(fontSize: 24),
),
onPressed: () {
_sendDataToSecondScreen(context);
},
)
],
),
);
}
// get the text in the TextField and start the Second Screen
void _sendDataToSecondScreen(BuildContext context) {
String textToSend = textFieldController.text;
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SecondScreen(text: textToSend,),
));
}
}
class SecondScreen extends StatelessWidget {
final String text;
// receive data from the FirstScreen as a parameter
SecondScreen({Key key, @required this.text}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Second screen')),
body: Center(
child: Text(
text,
style: TextStyle(fontSize: 24),
),
),
);
}
}
Передача данных на предыдущий экран
При передаче данных обратно необходимо выполнить следующие действия:
-
На
FirstScreen
помощьюNavigator
нажмите (запустите)SecondScreen
вasync
методе и дождитесь результата, который он вернет после завершения.final result = await Navigator.push( context, MaterialPageRoute( builder: (context) => SecondScreen(), ));
-
На
SecondScreen
данные, которые вы хотите передать обратно, в качестве параметра приSecondScreen
Navigator
.Navigator.pop(context, 'Hello');
-
Тогда в
FirstScreen
await
завершится, и вы можете использовать результат.setState(() { text = result; });
Вот полный код для main.dart
для вашей справки.
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
title: 'Flutter',
home: FirstScreen(),
));
}
class FirstScreen extends StatefulWidget {
@override
_FirstScreenState createState() {
return _FirstScreenState();
}
}
class _FirstScreenState extends State<FirstScreen> {
String text = 'Text';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('First screen')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(32.0),
child: Text(
text,
style: TextStyle(fontSize: 24),
),
),
RaisedButton(
child: Text(
'Go to second screen',
style: TextStyle(fontSize: 24),
),
onPressed: () {
_awaitReturnValueFromSecondScreen(context);
},
)
],
),
),
);
}
void _awaitReturnValueFromSecondScreen(BuildContext context) async {
// start the SecondScreen and wait for it to finish with a result
final result = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SecondScreen(),
));
// after the SecondScreen result comes back update the Text widget with it
setState(() {
text = result;
});
}
}
class SecondScreen extends StatefulWidget {
@override
_SecondScreenState createState() {
return _SecondScreenState();
}
}
class _SecondScreenState extends State<SecondScreen> {
// this allows us to access the TextField text
TextEditingController textFieldController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Second screen')),
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(32.0),
child: TextField(
controller: textFieldController,
style: TextStyle(
fontSize: 24,
color: Colors.black,
),
),
),
RaisedButton(
child: Text(
'Send text back',
style: TextStyle(fontSize: 24),
),
onPressed: () {
_sendDataBack(context);
},
)
],
),
);
}
// get the text in the TextField and send it back to the FirstScreen
void _sendDataBack(BuildContext context) {
String textToSendBack = textFieldController.text;
Navigator.pop(context, textToSendBack);
}
}