父子組件之間的傳值
父組件
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類傳值,格式:參數(shù)名稱:參數(shù)值
),
),
);
}
}
class MyText extends StatelessWidget {
const MyText({Key key,@required this.str1}) : super(key: key); //接收傳遞過來的值,使用@required修飾,表示為必傳參數(shù)
final String str1; //定義接收參數(shù)
@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()
)); //第一個參數(shù)是上下文霞赫,第二個參數(shù)是路由參數(shù)
},
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); //使用構造函數(shù)
}
void main() {
runApp(MaterialApp(
title: "導航之間的傳值",
home: FirstController(
/**
* 為FirstController的 models 屬性賦值秃诵,
* 傳遞的是一個數(shù)組,數(shù)組中都是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( //創(chuàng)建一個列表
itemCount: models.length,
itemBuilder: (BuildContext context, int index) {
return ListTile(
leading: Icon(Icons.iso),
title: Text(models[index].title),
onTap: (){ //cell的響應方法,點擊cell會執(zhí)行這個方法
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),),
);
}
}
返回頁面?zhèn)髦?/p>
創(chuàng)建一個TipRoute路由,它接受一個提示文本參數(shù)萄金,負責將傳入它的文本顯示在頁面上狼钮,另外TipRoute中我們添加一個“返回”按鈕,點擊后在返回上一個路由的同時會帶上一個返回參數(shù)捡絮,下面我們看一下實現(xiàn)代碼熬芜。
class TipRoute extends StatelessWidget {
TipRoute({
Key key,
@required this.text, // 接收一個text參數(shù)
}) : 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(
// 路由參數(shù)
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:"頁面?zhèn)髦?,); //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梅掠,否則會不執(zhí)行onGenerateRoute方法
},
onGenerateRoute: (RouteSettings setting){ //1酌住,使用navigator.pushname方法時,在未找到路由名稱阎抒,會執(zhí)行這個里面的方法
// 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: "傳遞參數(shù)"); //2且叁,打開新頁面都哭,傳遞參數(shù)
},
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,接收上個頁面?zhèn)鬟f對參數(shù)
return Scaffold(
appBar: AppBar(title: Text("頁面二"),),
body: Center(
child:Column(
children: <Widget>[
// Text(value),
FlatButton(
child: Text("返回"),
onPressed: (){
Navigator.pop(context);
},
)
],
),
),
);
}
}