美文网首页
[Flutter开发]03.Flutter中的路由管理

[Flutter开发]03.Flutter中的路由管理

作者: 沈枫_SerenF | 来源:发表于2020-03-10 14:59 被阅读0次

    Flutter中的路由管理,就是管理页面之间如何跳转。无论是Android还是iOS,导航管理都会维护一个路由栈,路由入栈(push)操作对应打开一个新页面(或者叫新路由),路由出栈(pop)操作对应页面关闭操作,而路由管理主要是指如何来管理路由栈。

    而路由管理需要用到以下组件,我们分别来认识一下。

    Navigator

    Navigator提供了一系列方法来管理路由栈:

    1. Future push(BuildContext context, Route route),此方法是静态方法:
    Navigator.push(BuildContext context, Route route)
    

    对应的实例方法是:

    Navigator.of(context).push(Route route)
    
    1. bool pop(BuildContext context, [ result ])

    result为页面关闭时返回给上一个页面的数据。

    MaterialPageRoute

    MaterialPageRoute用来构建Route,构建函数如下:

    MaterialPageRoute({
        WidgetBuilder builder,
        RouteSettings settings,
        bool maintainState = true,
        bool fullscreenDialog = false,
      })
    
    • builder:是一个WidgetBuilder类型的回调函数,作用是构建路由页面的实例,返回一个widget。
    • settings:包含路由的配置信息,如路由名称、是否初始路由(首页)。
    • maintainState:默认情况下,当入栈一个新路由时,原来的路由仍然会被保存在内存中,如果想在路由没用的时候释放其所占用的所有资源,可以设置为false。
    • fullscreenDialog:在iOS中,如果fullscreenDialog为true,新页面将会从屏幕底部滑入。

    以上的方式是非命名路由,下面我来讲一下命名路由。

    命名路由

    所谓命名路由,无非就是先给路由起一个名字,然后就可以通过路由名字直接打开新的路由了,这为路由管理带来了一种直观、简单的方式。

    我们可以通过注册路由表的方式,然后通过路由名字打开新路由时,在路由表中,一个名字对应一个生成相应的路由的回调函数,应用会根据路由名字在路由表中查找到对应的回调函数(WidgetBuilder),然后调用该回调函数生成路由widget并返回。

    MaterialApp(
      title: 'Flutter Demo',
      initialRoute:"/home", //名为"/home"的路由作为应用的首页
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      //注册路由表
      routes:{
       "new_page":(context) => NewRoute(),
       "/home":(context) => MyHomePage(title: 'Demo Home Page'), //注册首页路由
      } 
    );
    

    要通过路由名称来打开新路由,也很简单:

    Navigator.pushNamed(context, "new_page");
    

    或者:

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

    我们看到上面的第二个push方法中传递一个参数'hi',那么在新路由中实际上可以通过RouteSetting对象获取这个参数:

    class EchoRoute extends StatelessWidget {
    
      @override
      Widget build(BuildContext context) {
        //路由参数  
        var args=ModalRoute.of(context).settings.arguments;
        //...
      }
    }
    

    onGenerateRoute

    MaterialApp有一个onGenerateRoute属性,当调用Navigator.pushNamed(...)打开命名路由时,如果指定的路由名在路由表中已注册,则会调用路由表中的builder函数来生成路由组件;如果路由表中没有注册,就会调用onGenerateRoute来生成路由。一般我们可以在该回调中进行统一的权限控制,比如:

    MaterialApp(
      ... //省略
      onGenerateRoute:(RouteSettings settings){
          return MaterialPageRoute(builder: (context){
               String routeName = settings.name;
           // 如果访问的路由页需要登录,但当前未登录,则直接返回登录页路由,
           // 引导用户登录;其它情况则正常打开路由。
         }
       );
      }
    );
    

    WillPopScope

    Flutter中可以通过WillPopScope来实现导航返回按钮拦截。其默认构造函数如下:

    const WillPopScope({
      ...
      @required WillPopCallback onWillPop,
      @required Widget child
    })
    

    其中,onWillPop是一个回调函数,当用户点击返回按钮时被调用。该回调需要返回一个Future对象,如果返回的Future最终值为false时,则不会返回;如果最终值为true时,当前路由出栈退出。我们需要提供这个回调来决定是否退出。

    举个例子,为了防止用户误触返回键退出,我们设定当用户在1秒内点击两次返回按钮时,则退出;如果间隔超过1秒则不退出,并重新记时。代码如下:

    class TestRoute extends StatefulWidget {
      @override
      TestRouteState createState() {
        return new TestRouteState();
      }
    }
    
    class TestRouteState extends State<TestRoute> {
      DateTime _lastClickTime; //上次点击时间
    
      @override
      Widget build(BuildContext context) {
        return new WillPopScope(
            onWillPop: () async {
              if (_lastClickTime == null ||
                  DateTime.now().difference(_lastClickTime) > Duration(seconds: 1)) {
                //两次点击间隔超过1秒则重新计时
                _lastClickTime = DateTime.now();
                return false;
              }
              return true;
            },
            child: Container(
              alignment: Alignment.center,
              child: Text("test demo"),
            )
        );
      }
    }
    

    相关文章

      网友评论

          本文标题:[Flutter开发]03.Flutter中的路由管理

          本文链接:https://www.haomeiwen.com/subject/bkxmzqtx.html