当我学习 Flutter 时,我开始学习导航。我想在屏幕之间传递数据,类似于在 Android 中的活动之间传递数据以及在 iOS 中的视图控制器之间传递数据。我如何在 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);
}
}
获得完美解决方案:
从第一个屏幕导航到其他屏幕:
Navigator.pushNamed(context, "second",arguments: {"name" :
"Bijendra", "rollNo": 65210});
},
在构建方法的第二个屏幕上获取为:
@override
Widget build(BuildContext context) {
final Map<String, Object>rcvdData = ModalRoute.of(context).settings.arguments;
print("rcvd fdata ${rcvdData['name']}");
print("rcvd fdata ${rcvdData}");
return Scaffold(appBar: AppBar(title: Text("Second")),
body: Container(child: Column(children: <Widget>[
Text("Second"),
],),),);
}
通过在构造函数中传递变量,此解决方案非常简单:
第一页:
Navigator.of(context).push(MaterialPageRoute(builder:(context)=>SecondPage('something')));
第二页:
class SecondPage extends StatefulWidget {
String something;
SecondPage(this.something);
@override
State<StatefulWidget> createState() {
return SecondPageState(this.something);
}
}
class SecondPageState extends State<SecondPage> {
String something;
SecondPageState(this.something);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
//now you have passing variable
title: Text(something),
),
...
}
最简单的方法
第一页.dart
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => PasswordRoute(usernameController)));
//usernameController是String值,如果要传多个值全部加
第二页.dart
class PasswordRoute extends StatefulWidget {
final String usernameController;//if you have multiple values add here
PasswordRoute(this.usernameController, {Key key}): super(key: key);//add also..example this.abc,this...
@override
State<StatefulWidget> createState() => _PasswordPageState();
}
class _PasswordPageState extends State<PasswordRoute> {
@override
Widget build(BuildContext context) {
...child: Text(widget.usernameController);
}
}
上面的答案对于小型应用程序很有用,但如果你想消除不断担心小部件状态的头痛,谷歌提供了 Provider 包。 https://pub.dev/packages/provider
看看那个,或观看 Andrea Bizzotto 的这些视频: https ://www.youtube.com/watch?v=MkFjtCov62g // 提供者:基本指南 https://www.youtube.com/watch?v =O71rYKcxUgA&t=258s // 提供者:简介
学习如何使用 Provider 包,你就可以终身受益 :)
First Screen : //发送数据到第二屏
Navigator.push(context, MaterialPageRoute(builder: (context) {
return WelcomeUser(usernameController.text);
}));
第二屏: //从第一屏获取数据
final String username;
WelcomeUser(this.username);
//使用数据显示
body: Container(
child: Center(
child: Text("Welcome "+widget.username,
textAlign: TextAlign.center,
),
),
),
Flutter 中的导航器类似于 Android 中的 Intent。我们正在处理两个类 FirstScreen 和 SecondScreen。
为了在第一个屏幕到第二个屏幕之间传递数据,请执行以下操作:首先在 SecondScreen 类构造函数中添加参数
现在在 FirstScreen 类中提供参数
Navigator.push(context, MaterialPageRoute(builder: (context)=>SecondScreen(key_name:"Desired Data"));
因此,在上面的行中,“key_name”是 SecondScreen 类中给出的参数的名称。“所需数据”是应通过密钥传递给 SecondScreen 类的数据。
这样你就完成了!!!
如果你使用 get 包,那么试试这个。使用 get 包传递数据
检查获取包包链接
我只是想在这里帮助那 1% 可能会经历我所做的事情的人 Lol
不要忘记在第一页的“Navigator.push”前面加上一个“await”,否则从第二页弹出时不会有数据返回到第一页...
1)从您要推送的位置:
onPressed: () async {
await Navigator.pushNamed(context, '/edit',
arguments: userData);
setState(() {
userData = userData;
});}
2)从你想弹出的地方:
void updateData() async{
WorldTime instance = locations;
await instance.getData();
Navigator.pop(context, userData);
}