flutter Route路由基本用法


https://blog.csdn.net/senkai123/article/details/102948524

 

Flutter 命名路由、路由組、路由退出、路由堆棧

 

在flutter中需要進行頁面跳轉,也是需要用到路由Route,關鍵Navigator與Route,Navigator負責單元Route路由,壓入和彈出,單元路由也就是我們需要跳轉頁面 ,比如HomePage()

 

Navigator關鍵使用的4個屬性

 

•initialRoute: 初始路由的,也就是進入APP,默認頁面

•onGenerateRoute: 路由攔截器

•onUnknownRoute: 找不到頁面,也就是404

•routes : 路由集合,也就在執行路由跳轉的時候,會到路由集合里面的子路由進行匹配,如果匹配 到那么就調整到指定頁面

 

路由跳轉 方式:

 

1.通過路由名打開新路由頁面

 

通過路由名稱來打開新路由,可以使用Navigator 的pushNamed方法:

 

Future pushNamed(BuildContext context, String routeName,{Object arguments})

1

調用:

 

onPressed: () {

//不帶參數

  Navigator.pushNamed(context, "new_page");

  //帶參數,可以指定單個參數,或者多個, arguments: {}

  Navigator.of(context).pushNamed("new_page", arguments: "hi");

},

 

頁面承接帶過來的參數

 

  String tmp = ModalRoute.of(context).settings.arguments.toString();

1

2.匿名路由打開新路由頁面

 

Navigator.push( context, MaterialPageRoute(builder: (context) {

              return HomePage();

           }));

 

傳參:

 

  final Map<String, WidgetBuilder> _routes = {

    '/sign': (context, {arguments}) => SignPage(arguments: arguments),

  };

 

接參:

 

class SignPage extends StatelessWidget {

  final Map arguments;

  SignPage({Key key, this.arguments}) : super(key: key) {

  }

 

  @override

  Widget build(BuildContext context) {

    String tmp2 = this.arguments.toString();

  }

}

 

路由集合(路由表)與onGenerateRoute的關系

onGenerateRoute接受一個 Route 工廠函數

 

final RouteFactory onGenerateRoute;

1

路由攔截源碼,從攔截到路由之后,首先從路由表中拿到路由的 builder,如果能夠拿到 builder,則判斷是否存在 RouteSettings,如果存在則直接通關構造函數的 arguments 傳遞給頁面 Page Widget。本質就是按照路由名字匹配路由表,然后跳轉到正確頁面中

 

Route _routeGenerator(RouteSettings settings) {

    final String name = settings.name;

    final Function pageBuilder = this._routes[name];

    if (pageBuilder != null) {

      if (settings.arguments != null) {

        // 如果透傳了參數

        return MaterialPageRoute(

            builder: (context) =>

                pageBuilder(context, arguments: settings.arguments));

      } else {

        // 沒有透傳參數

        return MaterialPageRoute(builder: (context) => pageBuilder(context));

      }

    }

    return MaterialPageRoute(builder: (context) => HomeContent());

  }

 

路由的使用方式

第一個種,初始化執行路線,initialRoute -> onGenerateRoute -> onUnknownRoute, 路由跳轉Navigator.pushNamed(context, “secondPage”); ,之后會到onGenerateRoute ,進行路由攔截匹配,如果能正確匹配到,那么跳轉到指定頁面

例子:

 

import 'package:flutter/material.dart';

 

class NavigatorPage extends StatefulWidget {

 @override

 _NavigatorPageState createState() => _NavigatorPageState();

}

 

class _NavigatorPageState extends State<NavigatorPage> {

 @override

 Widget build(BuildContext context) {

  return Scaffold(

   appBar: AppBar(

    title: Text('Navigator'),

   ),

   body: Column(

    children: <Widget>[

     Text('Navigator的高度為infinity'),

     Text('如果直接父級非最上級也是infinity會產生異常'),

     Container(

      height: 333,

      color: Colors.amber.withAlpha(111),

      child: Navigator( // Navigator

       initialRoute: '/abc',

       onGenerateRoute: (val) {

        RoutePageBuilder builder;

        switch (val.name) {

         case '/abc':

          builder = (BuildContext nContext, Animation<double> animation, Animation<double> secondaryAnimation) => Column(

           // 並沒有在 MaterialApp 中設定 /efg 路由

           // 因為Navigator的特性 使用nContext 可以跳轉 /efg

           children: <Widget>[

            Text('呵呵呵'),

            RaisedButton(

             child: Text('去 /efg'),

             onPressed: () {

              Navigator.pushNamed(nContext, '/efg');

             },

            )

           ],

          );

         break;

         case '/efg':

          builder = (BuildContext nContext, Animation<double> animation, Animation<double> secondaryAnimation) => Row(

           children: <Widget>[

            RaisedButton(

             child: Text('去 /hhh'),

             onPressed: () {

              Navigator.pushNamed(nContext, '/hhh');

             },

            )

           ],

          );

         break;

         default:

          builder = (BuildContext nContext, Animation<double> animation, Animation<double> secondaryAnimation) => Center(

           child: RaisedButton(

            child: Text('去 /abc'),

            onPressed: () {

             Navigator.pushNamed(nContext, '/abc');

            },

           )

          );

        }

        return PageRouteBuilder(

         pageBuilder: builder,

         // transitionDuration: const Duration(milliseconds: 0),

        );

       },

       onUnknownRoute: (val) {

        print(val);

       },

       observers: <NavigatorObserver>[]

      ),

     ),

     Text('Navigator執行尋找路由順序'),

     Text('initialRoute'),

     Text('onGenerateRoute'),

     Text('onUnknownRoute'),

    ],

   ),

  );

 }

}

 

第二個種,初始化執行路線,routes ->onUnknownRoute,路由跳轉Navigator.pushNamed(context, “secondPage”);,之后會到routes 路由集合之后,能匹配到正確的路由子路由,那么就跳轉到子路由中

例子:

 

import 'package:flutter/material.dart';

import 'package:flutter_routes/errorpage.dart';

import 'package:flutter_routes/homepage.dart';

import 'package:flutter_routes/navigator_with_result.dart';

import 'package:flutter_routes/page1.dart';

import 'package:flutter_routes/page2.dart';

import 'package:flutter_routes/page3.dart';

import 'package:flutter_routes/page4.dart';

import 'package:flutter_routes/page5.dart';

import 'package:flutter_routes/pageroutebuilderresult.dart';

import 'package:flutter_routes/splash.dart';

import 'package:flutter_routes/testpageroutebuilder.dart';

import 'package:flutter_routes/todo.dart';

import 'package:flutter_routes/welcome.dart';

 

void main() => runApp(MyApp());

 

class MyApp extends StatelessWidget {

  @override

  Widget build(BuildContext context) {

    return MaterialApp(

      title: 'Flutter路由',

      theme: ThemeData(

        primarySwatch: Colors.blue,

      ),

//      路由集合

      routes: {

        '/page1': (context) => Page1(),

        '/page2': (context) => Page2(),

        '/page3': (context) => Page3(),

        '/page4': (context) => Page4(),

        '/page5': (context) => Page5(),

        '/todo': (context) => TodosScreen(),

        '/splash': (context) => Splash(),

        '/welcome': (context) => Welcome(),

        '/homepage': (context) => HomePage(),

        '/PageRouteBuilder': (context) => TestPageRouteBuilder(),

        '/PageRouteBuilderResult': (context) => PageRouteBuilderResult(),

      },

//      找不到路由,顯示的錯誤頁面

      onUnknownRoute: (RouteSettings setting) {

        String name = setting.name;

        print("未匹配到路由:$name");

        return new MaterialPageRoute(builder: (context) {

          return new ErrorPage();

        });

      },

      home: Page1(),

    );

  }

}

 

 

Page1 頁面

 

import 'package:flutter/foundation.dart';

import 'package:flutter/material.dart';

 

class Page1 extends StatelessWidget {

 

  Page1({Key key}) : super(key: key);

 

  @override

  Widget build(BuildContext context) {

    return Scaffold(

      appBar: AppBar(

        title: Text('page1'),

      ),

      body: Center(

        child: RaisedButton(

          child: Text('跳轉到Page2'),

          onPressed: () {

//            路由跳轉

            Navigator.pushNamed(context, '/page2');

          },

        ),

      ),

    );

  }

}

 

 

在實際開發過程中,建議用命名路由方式來跳轉新的頁面,便於維護,開發項目

 

路由堆棧的使用方式

1、在用這種方式路由跳轉新頁面的時候,是把頁面放在堆棧里面,這個棧的特性就是,先進后出, Navigator.push 或者 pushNamed 實現的,每次都是把頁面壓入堆棧,在回退 的時候會回退到上一跳頁面

 

Navigator.of(context).pushNamed('/search');

1

2.如果需要清空堆棧,比如我需要直接返回首頁,之前的所有路由全部干掉,堆棧清空

 

Navigator.of(context).pushNamedAndRemoveUntil

1

頁面退出堆棧

 

 Navigator.pop(context, "我是返回值"),

1

參考文章

https://blog.csdn.net/weixin_30512027/article/details/85334391

https://blog.csdn.net/weixin_34999505/article/details/86760606

————————————————

版權聲明:本文為CSDN博主「逐流間隔年」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。

原文鏈接:https://blog.csdn.net/senkai123/java/article/details/102948524

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM