Flutter 局部路由实现

摘要:Flutter是借鉴React的开发思想实现的,在子组件的插槽上,React有this.props.children,Vue有。当然Flutter也有类似的Widget,那就是Navigator,不过是以router的形式实现(像)。

Flutter是借鉴React的开发思想实现的,在子组件的插槽上,React有this.props.children,Vue有<slot></slot>。 当然Flutter也有类似的Widget,那就是Navigator,不过是以router的形式实现(像<router-view></router-view>)。


Navigator的使用无非3个属性

initialRoute: 初始路由 
onGenerateRoute: 匹配路由 
onUnknownRoute: 404


在实现层面

首先:Navigator的高度为infinity。如果直接父级非最上级也是infinity会产生异常,例如,Scaffold -> Column -> Navigator。所以:Navigator需要附件限制高度,例如:Scaffold -> Column -> Container(height: 300) -> Navigator

然后:在onGenerateRoute属性中,使用第一个BuildContext参数,能够在MaterialApp未设置route的情况下使用Navigator.pushNamed(nContext, '/efg');跳到对应的子路由中。

最后:Navigator执行寻找路由顺序是 initialRoute -> onGenerateRoute -> onUnknownRoute,这个和React的Route是类似的。


最后附上源码

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'),
        ],
      ),
    );
  }
}

项目地址: https://github.com/zhongmeizhi/fultter-example-app

撸完代码记得给颗星哦。


本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://shenqiku.cn/article/FLY_3640