一、Flutter 頁面跳轉及參數傳遞
在Android中,可以通過Intents來在Activity之間切換或調用外部組件,但Flutter不具有Intents的概念,那麼我們如何在Flutter中來實現屏幕切換呢?要在Flutter中切換屏幕,您可以訪問路由以繪製新的Widget。 管理多個屏幕有兩個核心概念和類:Route (路由)和 Navigator(導航器)。Route是應用程序的“屏幕”或“頁面”的抽象(可以認爲是Activity), Navigator是管理Route的Widget。Navigator可以通過push和pop route以實現頁面切換。
Flutter和Android相似,Android中需要在AndroidManifest.xml中聲明您的Activitie組件,在Flutter中,您可以將具有指定Route的Map傳遞到頂層MaterialApp,
首先我們看一下通過路由實現的頁面切換效果圖:
其中點擊跳轉到RouteA中是通過pushName跳轉的,沒有攜帶數據。點擊跳轉到RouteB中是通過push跳轉的,並且攜帶了一個對象,然後在RouteB中接收顯示,在RouteB中返回的時候也將處理結果返回,在StudyRoute中接收處理RouteB返回的處理結果。下面我們看一下這兩種route具體實現過程:
1、MaterialApp中的routes聲明如下:
return new MaterialApp(
theme: ThemeData(primarySwatch: Colors.blue),
routes: <String, WidgetBuilder>{
'/RouteA': (BuildContext context) {
return new RouteA();
},
'/RouteB': (BuildContext context) {
return new RouteB(product: new Product("測試", "我是描述"),);
},
},
...
);
2、通過Navigator指定跳轉
- 通過pushNamed跳轉頁面,這種方式跳轉的時候一般沒法傳遞數據,但可以接收返回值。類似與Android的startActivityForResult
Navigator.pushNamed(context, '/RouteA').then((Object result) async {
print('======$result');
});
或者
Navigator.of(context).pushNamed('/RouteA').then((Object result){
print('======$result');
});
注意:通過pushNamed跳轉的路由必須在MaterialApp的routes中聲明路由跳轉路徑。
- 通過push的方式跳轉頁面,同時傳遞數據到下一個頁面,並接收處理後的結果
Navigator.push<String>(context,
new MaterialPageRoute(builder: (BuildContext context) {
return new RouteB(product: _product,);
}),).then((String result){
print("===================$result");
});
3、實現案例目錄
StudyRoute代碼如下:
class StudyRoute extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return new MaterialApp(
theme: ThemeData(primarySwatch: Colors.blue),
routes: <String, WidgetBuilder>{
'/RouteA': (BuildContext context) {
return new RouteA();
},
'/RouteB': (BuildContext context) {
return new RouteB(product: new Product("測試", "我是描述"),);
},
},
home: new Scaffold(
appBar: new AppBar(
title: new Text('Flutter Route使用'),
),
body: new Study(),
),
);
}
}
class Study extends StatefulWidget {
@override
State<StatefulWidget> createState() {
// TODO: implement createState
Product product = new Product("Intent在Flutter中等價於什麼?", "在Android中,Intents主要有兩種使用場景:在Activity之間切換,以及調用外部組件。 Flutter不具有Intents的概念,但如果需要的話,Flutter可以通過Native整合來觸發Intents。要在Flutter中切換屏幕,您可以訪問路由以繪製新的Widget。 管理多個屏幕有兩個核心概念和類:Route 和 Navigator。Route是應用程序的“屏幕”或“頁面”的抽象(可以認爲是Activity), Navigator是管理Route的Widget。Navigator可以通過push和pop route以實現頁面切換。和Android相似,您可以在AndroidManifest.xml中聲明您的Activities,在Flutter中,您可以將具有指定Route的Map傳遞到頂層MaterialApp實例");
return _StudyState(product);
}
}
class _StudyState extends State<Study> {
final Product _product;
_StudyState(this._product);
void _onTapA() {
Navigator.pushNamed(context, '/RouteA');
Navigator.of(context).pushNamed('/RouteA');
}
void _onTapB() {
Navigator.push<String>(context,
new MaterialPageRoute(builder: (BuildContext context) {
return new RouteB(product: _product,);
}),).then((String result){
print("===================$result");
//Fluttertoast.showToast(msg: result);
});
}
@override
Widget build(BuildContext context) {
// TODO: implement build
return new Center(
child: new Container(
width: 300,
height: 300,
//color: Colors.blueAccent,
child: new Column(
children: <Widget>[
new Expanded(
flex: 1,
child: new Container(
width: 300,
//color: Colors.red,
decoration: BoxDecoration(shape: BoxShape.circle,color: Colors.red),
child: new InkWell(
onTap: _onTapA,
child: new Center(
child: new Text('跳轉到Route A'),
)
),
),
),
new Expanded(
flex: 1,
child: new Container(
width: 300,
decoration: BoxDecoration(shape: BoxShape.circle,color: Colors.green),
child: new InkWell(
onTap: _onTapB,
child: new Center(
child: new Text('跳轉到Route B',textAlign: TextAlign.center),
)
),
),
),
],
),
),
);
}
}
通過pushName跳轉到RouteA,並且通過pop返回到StudyRoute頁面。
class RouteA extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return new Scaffold(
//automaticallyImplyLeading: false關閉返回的部件
appBar: new AppBar(
title: new Text('我是Route A'),
leading: Builder(builder: (BuildContext context) {
return new IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
Navigator.pop(context, "攜帶的參數");
});
}),
),
body: new Container(
child: new Center(
child: new Text('Route A 頁面顯示'),
)
),
);
}
}
在RouteB中接收StudyRoute傳遞過來的參數並顯示,同時用戶點擊返回的時候將返回結果回傳給StudyRoute
class RouteB extends StatelessWidget{
final Product product;
const RouteB({Key key, @required this.product}) : super(key: key);
@override
Widget build(BuildContext context) {
// TODO: implement build
return new Scaffold(
appBar: new AppBar(
title: new Text('Flutter RouteB'),
leading: Builder(builder: (BuildContext context){
return new IconButton(icon: Icon(Icons.arrow_back_ios), onPressed:(){
Navigator.pop(context,"我是返回的數據");
});
}),
),
body: new Center(
child: new Column(
children: <Widget>[
new Text(product.title,style: TextStyle(color: Color(0xFF333333),fontSize: 18,fontWeight: FontWeight.bold),),
new Text(product.description,softWrap: true,),
],
),
),
);
}
}