dart - 在 Flutter 中的屏幕之间传递数据
问题描述
当我学习 Flutter 时,我开始学习导航。我想在屏幕之间传递数据,类似于在 Android 中的活动之间传递数据以及在 iOS 中的视图控制器之间传递数据。我如何在 Flutter 中做到这一点?
相关问题:
解决方案
这个答案将涵盖向前传递数据和向后传递数据。与 Android 活动和 iOS 视图控制器不同,Flutter 中的不同屏幕只是小部件。在它们之间导航涉及创建称为路由的东西,并使用 将Navigator
路由推入和弹出堆栈。
将数据转发到下一个屏幕
要将数据发送到下一个屏幕,请执行以下操作:
使
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
,包含您想要在弹出时作为参数传回的数据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);
}
}
推荐阅读
- django - django REST过滤器查询外键lookup_field
- reactjs - react -native 在滚动视图中播放视频,如 instagram
- python - Django 在其他表中看不到 fk
- abap - AUTHORITY-CHECK 用于复杂的选择字段(如 SELECT-OPTIONS)
- autocad - AutoCad 的 ELLIPSE 的 DXF 代码问题
- c++ - 给定哈希函数,解码消息的最佳方法是什么
- angular - 仅在 ng 测试期间“找不到命名空间”
- database - 尝试从数据库中选择单行时出现奇怪的错误
- excel - 使用键盘 Excel VBA 在宏中进行限制
- powershell - Azure 自动化 Runbook 无法将 webhookdata 解析为 JSON 对象