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

 

posted @ 2020-04-03 20:17  sundayswift  阅读(4093)  评论(0编辑  收藏  举报