• <ul id="cgeq2"></ul>
  • 歡迎您光臨深圳塔燈網(wǎng)絡(luò)科技有限公司!
    電話圖標(biāo) 余先生:13699882642

    網(wǎng)站百科

    為您解碼網(wǎng)站建設(shè)的點(diǎn)點(diǎn)滴滴

    Flutter學(xué)習(xí)筆記之路由簡(jiǎn)單實(shí)用

    發(fā)表日期:2018-12 文章編輯:小燈 瀏覽次數(shù):2890

    路由的簡(jiǎn)單實(shí)用

    • 基本的界面跳轉(zhuǎn)
    class FirstScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("first Screen"), ), body: Center( child: RaisedButton( child: Text("this is first screen"), onPressed: () { //go to second screen Navigator.push(context, MaterialPageRoute(builder: (context)=>SecodeScreen())); }, )), ); } } 
    Screenshot_1545962905.png

    如上圖所示,第一個(gè)界面中包含了一個(gè)按鈕,在按鈕的點(diǎn)擊事件中

     Navigator.push(context, MaterialPageRoute(builder: (context)=>SecondScreen())); 

    這句代碼的意思將頁(yè)面SecondScreen壓入路由棧,在Android開發(fā)中我們也是同樣的使用一個(gè)回退棧管理我們的界面,既然有入棧操作,那么一定有出棧了,沒錯(cuò),下面看第二個(gè)界面的代碼:

    class SecondScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("second screen"), ), body: Center( child: RaisedButton( child: Text("go back"), onPressed: () { Navigator.pop(context); }, ), ), ); } } 

    我們使用了

     Navigator.pop(context); 

    將該本頁(yè)面彈出路由棧,從而返回到第一個(gè)頁(yè)面。
    以上就是例子可以在官方文檔中找到,這只是最簡(jiǎn)單的路由跳轉(zhuǎn),但是平時(shí)我們開發(fā)經(jīng)常需要在頁(yè)面之間傳值,所以下面我們來看看,flutter中路由如何傳遞參數(shù)。

    • 傳遞參數(shù)到新頁(yè)面
      我們繼續(xù)使用官方的例子,首先定義一個(gè)實(shí)體類,
    class Todo{ final String title; final String desc; Todo(this.title,this.desc); } 

    然后我們創(chuàng)建一個(gè)todoList

    class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( // This is the theme of your application. // // Try running your application with "flutter run". You'll see the // application has a blue toolbar. Then, without quitting the app, try // changing the primarySwatch below to Colors.green and then invoke // "hot reload" (press "r" in the console where you ran "flutter run", // or simply save your changes to "hot reload" in a Flutter IDE). // Notice that the counter didn't reset back to zero; the application // is not restarted. primarySwatch: Colors.blue, ), home: TodoScreen( todos: List.generate(10, (i) => Todo("title$i", "Desc$i"))), ); } } //列表頁(yè) class TodoScreen extends StatelessWidget { final List<Todo> todos; TodoScreen({Key key, @required this.todos}) : super(key: key);@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("todos"), ), body: ListView.builder( itemCount: todos.length, itemBuilder: (context, index) { return ListTile( title: Text(todos[index].title), onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => DetailScreen(todo: todos[index]))); }, ); }, ), ); } }//詳情頁(yè) class DetailScreen extends StatelessWidget { final Todo todo; DetailScreen({Key key, @required this.todo}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(todo.title), ), body: Center( child: Text(todo.desc), ), ); } } 

    在代碼里我們通過

    Navigator.push( context, MaterialPageRoute( builder: (context) => DetailScreen(todo: todos[index]))); }, ); 

    將todo傳到了詳情頁(yè),也就是通過構(gòu)造函數(shù)傳值,在flutter中一切都是widget,我們?cè)贒etailScreen里通過構(gòu)造函數(shù)接收即可。

    • 攜帶參數(shù)返回
      在Android開發(fā)中,我們通常使用startActivityForResult啟動(dòng)新頁(yè)面,這樣可以在當(dāng)前中重寫onActivityForResult來接收新頁(yè)面返回的參數(shù),那么在Flutter中該怎么坐呢,答案是使用Navigator.Pop(),
    class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( // This is the theme of your application. // // Try running your application with "flutter run". You'll see the // application has a blue toolbar. Then, without quitting the app, try // changing the primarySwatch below to Colors.green and then invoke // "hot reload" (press "r" in the console where you ran "flutter run", // or simply save your changes to "hot reload" in a Flutter IDE). // Notice that the counter didn't reset back to zero; the application // is not restarted. primarySwatch: Colors.blue, ), home: HomeScreen(), ); } }class SelectionButton extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return RaisedButton( child: Text('pick an option,any option'), onPressed: () { _navigateAndDisplaySelection(context); }, ); } } _navigateAndDisplaySelection(BuildContext context) async{ final result= await Navigator.push(context,MaterialPageRoute(builder: (context)=>SelectionScreen()) ); Scaffold.of(context) ..removeCurrentSnackBar() ..showSnackBar(SnackBar(content:Text("$result"))); } class HomeScreen extends StatelessWidget { @override Widget build(BuildContext context) { // TODO: implement build return Scaffold( appBar: AppBar( title: Text('home screen'), ), body: Center(child: SelectionButton()), ); } } class SelectionScreen extends StatelessWidget{ @override Widget build(BuildContext context) { // TODO: implement build return Scaffold( appBar: AppBar( title: Text("pick on option"), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Padding( padding: const EdgeInsets.all(8.0), child: RaisedButton( onPressed: (){ Navigator.pop(context,"yep"); }, child: Text("yep"), ), ), Padding( padding: const EdgeInsets.all(8.0), child: RaisedButton( onPressed: (){ Navigator.pop(context,"nope"); }, child: Text("nope"), ), ) ], ), ), ); }} 

    Pop方法的第二個(gè)參數(shù)是一個(gè)

    T result 

    這樣我們?cè)诔鰲5臅r(shí)候可以將參數(shù)帶回到上一個(gè)頁(yè)面,在上一個(gè)頁(yè)面中,我們這樣來接收

    _navigateAndDisplaySelection(BuildContext context) async{ final result= await Navigator.push(context,MaterialPageRoute(builder: (context)=>SelectionScreen()) ); Scaffold.of(context) ..removeCurrentSnackBar() ..showSnackBar(SnackBar(content:Text("$result"))); } 
    • 命名路由
      首先我們先定義一個(gè)路由映射關(guān)系
    class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData(primarySwatch: Colors.blue, ), home: FirstScreen(), routes: { '/second':(context)=>SecondScreen() }, ); } } 

    routes是一個(gè)map,用來管理我們定義的命名路由,之后我們就可以使用

    Navigator.pushNamed(context, "/second"); 

    來進(jìn)行路由的跳轉(zhuǎn),但是命名路由的方式有一個(gè)缺點(diǎn),就是不能直接攜帶參數(shù),只能靜態(tài)的在注冊(cè)路由的時(shí)候這么寫:

     routes: { '/second':(context)=>SecondScreen('params') }, 

    這樣在傳遞一些動(dòng)態(tài)的改變的參數(shù)時(shí)候就顯得不方便。

    • Hero控件
      這個(gè)很像Android里的共享元素,比如頁(yè)面A和頁(yè)面B都有一張相同的圖片,讓他們之間跳轉(zhuǎn)的時(shí)候,圖片無縫過渡,在Flutter使用Hero可以實(shí)現(xiàn)這一效果。下面來看看代碼中如何實(shí)現(xiàn)。
    class HeroApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Transition Demo', home: MainScreen(), ); } }class MainScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Main Screen'), ), body: GestureDetector( child: Hero( tag: 'imageHero', child: Image.network( 'https://raw.githubusercontent.com/flutter/website/master/src/_includes/code/layout/lakes/images/lake.jpg', ), ), onTap: () { Navigator.push(context, MaterialPageRoute(builder: (_) { return DetailScreen(); })); }, ), ); } }class DetailScreen extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: GestureDetector( child: Center( child: Hero( tag: 'imageHero', child: Image.network( 'https://raw.githubusercontent.com/flutter/website/master/src/_includes/code/layout/lakes/images/lake.jpg', ), ), ), onTap: () { Navigator.pop(context); }, ), ); } } 

    在不同頁(yè)面通過給Hero設(shè)置相同的tag,使它們關(guān)聯(lián)起來。

    總結(jié)

    Flutter中路由的常用使用方式基本介紹完了,主要參考官方例子,如有不足,歡迎指正。

    參考

    Flutte Doc


    本頁(yè)內(nèi)容由塔燈網(wǎng)絡(luò)科技有限公司通過網(wǎng)絡(luò)收集編輯所得,所有資料僅供用戶學(xué)習(xí)參考,本站不擁有所有權(quán),如您認(rèn)為本網(wǎng)頁(yè)中由涉嫌抄襲的內(nèi)容,請(qǐng)及時(shí)與我們聯(lián)系,并提供相關(guān)證據(jù),工作人員會(huì)在5工作日內(nèi)聯(lián)系您,一經(jīng)查實(shí),本站立刻刪除侵權(quán)內(nèi)容。本文鏈接:http://www.juherenli.com/17608.html
    相關(guān)APP開發(fā)