父子组件之间的传值
父组件
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Test",
home: Scaffold(
appBar: AppBar(
title: Text("Test"),
),
body: MyText(
str1: "传递的值", //向自定义的MyText类传值,格式:参数名称:参数值
),
),
);
}
}
class MyText extends StatelessWidget {
const MyText({Key key,@required this.str1}) : super(key: key); //接收传递过来的值,使用@required修饰,表示为必传参数
final String str1; //定义接收参数
@override
Widget build(BuildContext context) {
return Text(str1);
}
}
页面导航打开新页面和返回新页面
import 'package:flutter/material.dart';
void main(){
runApp(
MaterialApp(
title: "导航演示",
home: FirstScreen(),
)
);
}
class FirstScreen extends StatelessWidget {
const FirstScreen({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: Scaffold(
appBar: AppBar(title: Text("页面一"),),
body: Center(
child: RaisedButton(
onPressed: (){
Navigator.push(context, MaterialPageRoute(
builder: (context) => SecondScreen()
)); //第一个参数是上下文,第二个参数是路由参数
},
child: Text("打开新视图"),
),
),
)
);
}
}
class SecondScreen extends StatelessWidget {
const SecondScreen({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("页面二"),),
body: Center(
child: RaisedButton(
child: Text("返回"),
onPressed: (){
Navigator.pop(context);
},
),
),
);
}
}
导航之间的传值
import 'package:flutter/material.dart';
/**
* 建立一个model类
*/
class ProductModel{
final String title; //商品标题
final String desc; //商品详情
ProductModel(this.title,this.desc); //使用构造函数
}
void main() {
runApp(MaterialApp(
title: "导航之间的传值",
home: FirstController(
/**
* 为FirstController的 models 属性赋值,
* 传递的是一个数组,数组中都是ProductModel类,
* ProductModel有两个属性,所以传递形参传递两个
*/
models:List.generate(20, (i)=>ProductModel("商品 $i","商品 $i 的描述 $i"))
),
));
}
class FirstController extends StatelessWidget {
final List<ProductModel> models; //FirstController的属性,
FirstController({Key key,@required this.models}):super(key:key); //为属性models接收值
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("页面一"),),
body: ListView.builder( //创建一个列表
itemCount: models.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
leading: Icon(Icons.iso),
title: Text(models[index].title),
onTap: (){ //cell的响应方法,点击cell会执行这个方法
Navigator.push(context, MaterialPageRoute( //导航打开新视图
builder: (context) => SecondController(model:models[index]) //打开第二个页面,并传值,传递值的名称是model
));
},
);
},
),
);
}
}
class SecondController extends StatelessWidget {
final ProductModel model; //SecondController的model属性
SecondController({Key key,@required this.model}):super(key : key); //接收传递过来的值
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("页面二"),),
body: Center(child: Text(model.title),),
);
}
}
返回页面传值
创建一个TipRoute路由,它接受一个提示文本参数,负责将传入它的文本显示在页面上,另外TipRoute中我们添加一个“返回”按钮,点击后在返回上一个路由的同时会带上一个返回参数,下面我们看一下实现代码。
class TipRoute extends StatelessWidget {
TipRoute({
Key key,
@required this.text, // 接收一个text参数
}) : super(key: key);
final String text;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("提示"),
),
body: Padding(
padding: EdgeInsets.all(18),
child: Center(
child: Column(
children: <Widget>[
Text(text),
RaisedButton(
onPressed: () => Navigator.pop(context, "我是返回值"),
child: Text("返回"),
)
],
),
),
),
);
}
}
下面是打开新路由TipRoute的代码:
class RouterTestRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Center(
child: RaisedButton(
onPressed: () async {
// 打开`TipRoute`,并等待返回结果
var result = await Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return TipRoute(
// 路由参数
text: "我是提示xxxx",
);
},
),
);
//输出`TipRoute`路由返回结果
print("路由返回值: $result");
},
child: Text("打开提示页"),
),
);
}
}
命名路由
定义路由的名称,使用路由名称打开视图
import 'package:flutter/material.dart';
void main(){
runApp(
MaterialApp(
title: "导航演示",
routes: { //命名路由,1,注册路由表
"second_page": (context) => SecondScreen()
},
home: FirstScreen(),
)
);
}
class FirstScreen extends StatelessWidget {
const FirstScreen({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: Scaffold(
appBar: AppBar(title: Text("页面一"),),
body: Center(
child: RaisedButton(
onPressed: (){
Navigator.pushNamed(context, "second_page"); //2,就可以使用命名的路由打开新视图了
},
child: Text("打开新视图"),
),
),
)
);
}
}
class SecondScreen extends StatelessWidget {
const SecondScreen({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("页面二"),),
body: Center(
child: RaisedButton(
child: Text("返回"),
onPressed: (){
Navigator.pop(context);
},
),
),
);
}
}
命名路由传参
import 'package:flutter/material.dart';
void main(){
runApp(
MaterialApp(
title: "导航演示",
routes: { //命名路由,1,注册路由表
"second_page": (context) => SecondScreen()
},
home: FirstScreen(),
)
);
}
class FirstScreen extends StatelessWidget {
const FirstScreen({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: Scaffold(
appBar: AppBar(title: Text("页面一"),),
body: Center(
child: RaisedButton(
onPressed: (){
Navigator.of(context).pushNamed("second_page",arguments:"页面传值",); //2,使用命名的路由打开新视图,并传值
},
child: Text("打开新视图"),
),
),
)
);
}
}
class SecondScreen extends StatelessWidget {
const SecondScreen({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
var value = ModalRoute.of(context).settings.arguments; //3.在build方法中,接收传递过来的值
return Scaffold(
appBar: AppBar(title: Text("页面二"),),
body: Center(
child:Column(
children: <Widget>[
Text(value),
FlatButton(
child: Text("返回"),
onPressed: (){
Navigator.pop(context);
},
)
],
),
),
);
}
}
路由生成钩子
可以在onGenerateRoute
方法中做路由判断,比如判断用户是否有token打开不同的页面等等
import 'package:flutter/material.dart';
void main(){
runApp(
MaterialApp(
title: "导航演示",
routes: {
// "two_page":(context) => SecondScreen(), //注意,使用onGenerateRoute时,不能注册routes,否则会不执行onGenerateRoute方法
},
onGenerateRoute: (RouteSettings setting){ //1,使用navigator.pushname方法时,在未找到路由名称,会执行这个里面的方法
// setting.isInitialRoute; bool类型 是否初始路由
print(setting.name); //要跳转的路由名key
return PageRouteBuilder(
pageBuilder: (BuildContext context, _, __) {
//这里为返回的Widget
switch (setting.name) { //判断,如果是跳转路由名称是“two_page”,则返回SecondScreen()这个类
case "two_page":
return SecondScreen();
break;
default:
return FirstScreen();
}
},
opaque: false,
//跳转动画
transitionDuration: new Duration(milliseconds: 200),
transitionsBuilder:
(___, Animation<double> animation, ____, Widget child) {
return new FadeTransition(
opacity: animation,
child: new ScaleTransition(
scale: new Tween<double>(begin: 0.5, end: 1.0)
.animate(animation),
child: child,
),
);
});
},
home: FirstScreen(),
)
);
}
class FirstScreen extends StatelessWidget {
const FirstScreen({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
child: Scaffold(
appBar: AppBar(title: Text("页面一"),),
body: Center(
child: RaisedButton(
onPressed: (){
Navigator.of(context).pushNamed("two_page",arguments: "传递参数"); //2,打开新页面,传递参数
},
child: Text("打开新视图"),
),
),
)
);
}
}
class SecondScreen extends StatelessWidget {
const SecondScreen({Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
var value = ModalRoute.of(context).settings.arguments; //3,接收上个页面传递对参数
return Scaffold(
appBar: AppBar(title: Text("页面二"),),
body: Center(
child:Column(
children: <Widget>[
// Text(value),
FlatButton(
child: Text("返回"),
onPressed: (){
Navigator.pop(context);
},
)
],
),
),
);
}
}