美文网首页
Flutter路由

Flutter路由

作者: 卫殊琛 | 来源:发表于2020-07-16 10:23 被阅读0次

    1.基础用法

    1.1最基本的使用-跳转和退出

      跳转:Navigator.push()
      退出:Navigator.pop()
    

    2.进阶用法:路由表

    路由表:统一管理路由跳转问题

    使用方法:Navigator.pushNamed()
    

    2.1用法

      MaterialApp(
          // 定义APP启动时第一个显示的页面
          initialRoute: '/',
          routes: {
              //当navigating到‘/’ route时,构建FirstScreen widget
              '/': (context) => FirstScreen(),
              //当navigating 到"/second" route, 构建SecondScreen widget.
              '/second': (context) => SecondScreen(),
          },
        );
    

    跳转方法:

    跳转: Navigator.pushNamed(context, '/second');
    返回 :Navigator.pop(context);
    

    3.页面间值传递

    Navigator.pushNamed()源码

      @optionalTypeArgs
        static Future<T> pushNamed<T extends Object>(
          BuildContext context,
          //路由路径
          String routeName, {
          //携带的参数
          Object arguments,
         }) {
          return Navigator.of(context).pushNamed<T>(routeName, arguments: arguments);
        }
    

    arguments是跳转携带的参数,它是一个Object,意味着可以传递任意类型的参数!

    3.1 准备传递的数据

    多个数据时准备一个bean,

    class ScreenArguments {
      final String title;
      final String message;
       ScreenArguments(this.title, this.message);
    }
    

    3.2接受传递的数据

    创建一个页面来接受数据

    class ExtractArgumentsScreen extends StatelessWidget {
      static const routeName = '/extractArguments';
    
      @override
      Widget build(BuildContext context) {
        //获取传递的参数
        final ScreenArguments args = ModalRoute.of(context).settings.arguments;
        return Scaffold(
          appBar: AppBar(
              title: Text(args.title),
          ),
          body: Center(
              child: Text(args.message),
          ),
    );
    

    }
    通过 :ModalRoute.of(context).settings.arguments;获取传递的参数

    3.3,在MyApp里面注册

    MaterialApp(
      routes: {
        //或者 '/extractArguments' :(context) => ExtractArgumentsScreen(),
        ExtractArgumentsScreen.routeName: (context) => ExtractArgumentsScreen(),
      },     
    );
    

    3.4 跳转页面

     Navigator.pushNamed(
          context,
          ExtractArgumentsScreen.routeName,
          arguments: ScreenArguments(
            '我是被传递的title',
            '我是被传递的message.',
          )
    

    或者

    Navigator.push(
        context,
        MaterialPageRoute(
            builder: (context) => ExtractArgumentsScreen(),
            settings: RouteSettings(
                arguments: ScreenArguments(
                    '我是title',
                    '我是message.',
                 ),
             ) ,
         ),
       );
    

    4.携带参数退出

    4.1跳转页面:

     _push() async {
        final result = await Navigator.push(
          context,
          // Create the SelectionScreen in the next step.
          MaterialPageRoute(builder: (context) => SecondScreen()),
        );
      }
    

    其中result就是我们要的返回值

    4.2 返回页面:

    Navigator.pop(context, 'xxx!');
    

    由于源码中 pop的方法是Object,这里可以传递任意类型参数返回

      @optionalTypeArgs
      static void pop<T extends Object>(BuildContext context, [ T result ]) {
        Navigator.of(context).pop<T>(result);
      }
    

    5.高级用法

    PushAndRemove:跳转到一个新的页面并且销毁当前页
    popUntil:一直退出直到某一个页面
    pushReplacement:跳转到下一页的时候将之前所有的页面都销毁,先进入再退出
    popAndPushNamed:退出当前页面并且将新的页面放到它原来的位置上,先退出再进入
    maybePop:判断依据就是看当前路由是否处在栈中“最底部”的位置,如果不是就退出
    canPop:返回一个bool值,表示当前页面是否可以退出
    

    6第三方路由 FlutterBoost

    FlutterBoosts是阿里闲鱼团队开源的一款路由框架,新一代Flutter-Native混合解决方案。 FlutterBoost是一个Flutter插件,它可以轻松地为现有原生应用程序提供Flutter混合集成方案。FlutterBoost的理念是将Flutter像Webview那样来使用。在现有应用程序中同时管理Native页面和Flutter页面并非易事。 FlutterBoost帮你处理页面的映射和跳转,你只需关心页面的名字和参数即可

    6.1 在Flutter项目中添加依赖项。

    在pubspec.yaml中添加依赖(注意:flutter_boost的版本要和本地的Flutter保持一致,或者使用稳定的版本)

     flutter_boost:
      git:
        url: 'https://github.com/alibaba/flutter_boost.git'
        ref: '1.12.13+1'
    

    在app目录下的build.gradle中添加以下项目依赖

    dependencies {
     ...
    implementation project(':flutter_boost')
    

    }

    6.2 Flutter module项目使用FlutterBoost

    main方法中运行的rootWidget中注册

    @override
    void initState() {
    super.initState();
    
    FlutterBoost.singleton.registerPageBuilders({
      'flutterbus://flutterFirstPage': (pageName, params, _) {
        ...
        return FirstPage();
      },
      'flutterbus://flutterSecondPage': (pageName, params, _) {
        ...
        return SecondPage();
      },
    });
    
    FlutterBoost.handleOnStartPage();
    }
    
    @override
    Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Flutter Boost example',
        builder: FlutterBoost.init(),
        home: Container());
    }
    

    6.3 原生配置

    6.3.1 在MyApplication中初始化

    INativeRouter router = new INativeRouter() {
            @Override
            public void openContainer(Context context, String url, Map<String, Object> urlParams, int requestCode, Map<String, Object> exts) {
                String assembleUrl = Utils.assembleUrl(url, urlParams);
                PageRouter.openPageByUrl(context, assembleUrl, urlParams);
            }
    
        };
        FlutterBoost.BoostLifecycleListener boostLifecycleListener = new FlutterBoost.BoostLifecycleListener() {
    
            @Override
            public void beforeCreateEngine() {
            }
    
            @Override
            public void onEngineCreated() {
    
                // 注册MethodChannel,监听flutter侧的getPlatformVersion调用
                MethodChannel methodChannel = new MethodChannel(FlutterBoost.instance().engineProvider().getDartExecutor(), "flutter_native_channel");
                methodChannel.setMethodCallHandler((call, result) -> {
    
                    if (call.method.equals("getPlatformVersion")) {
                        result.success(Build.VERSION.RELEASE);
                    } else {
                        result.notImplemented();
                    }
    
                });
    
                // 注册PlatformView viewTypeId要和flutter中的viewType对应
                FlutterBoost
                        .instance()
                        .engineProvider()
                        .getPlatformViewsController()
                        .getRegistry()
                        .registerViewFactory("plugins.test/view", new TextPlatformViewFactory(StandardMessageCodec.INSTANCE));
    
            }
    
            @Override
            public void onPluginsRegistered() {
            }
    
            @Override
            public void onEngineDestroy() {
            }
    
        };
    
        Platform platform = new FlutterBoost
                .ConfigBuilder(this, router)
                .isDebug(true)
                .whenEngineStart(FlutterBoost.ConfigBuilder.ANY_ACTIVITY_CREATED)
                .renderMode(FlutterView.RenderMode.texture)
                .lifecycleListener(boostLifecycleListener)
                .build();
        FlutterBoost.instance().init(platform);
    

    6.3.2 AndroidManifest.xml 配置

     <activity
            android:name="com.idlefish.flutterboost.containers.BoostFlutterActivity"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
            android:hardwareAccelerated="true"
            android:screenOrientation="portrait"
            android:theme="@style/Theme.AppCompat"
            android:windowSoftInputMode="adjustResize">
            <meta-data
                android:name="io.flutter.embedding.android.SplashScreenDrawable"
                android:resource="@drawable/ic_launcher_background" />
        </activity>
    

    6.4 原生页面跳转到Flutter

    无参数跳转     
    
    Intent intent = BoostFlutterActivity.withNewEngine().url("flutterSecondPage").params(null)
                .backgroundMode(BoostFlutterActivity.BackgroundMode.opaque).build(this);
    startActivity(intent);
    

    有参跳转

    Map map = new HashMap();
    map.put("params1", "xx");
    map.put("params2", xxx);
    PageRouter.openPageByUrl(this, "first_page", map);
    

    有参 + 返回值

    Map map = new HashMap();
    map.put("params1", "xx");
    map.put("params2", xxx);
    PageRouter.openPageByUrl(this, "second_page", map, 101);
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (data != null && data.getExtras() != null) {
            Toast.makeText(this, data.getExtras().get(IFlutterViewContainer.RESULT_KEY).toString(),
             Toast.LENGTH_LONG).show();
            }
    }
    

    6.5Flutter 之间跳转

    // 无参
    FlutterBoost.singleton.open('second_page');
    
    // 有参
    FlutterBoost.singleton.open('second_page', urlParams: {'params1': 'xx', 'params2': xx});
    
    // 有参 + 返回值
    FlutterBoost.singleton.open('second_page', urlParams: { 'params1': 'xx', 'params2': xx  })
     .then((Map value) { print('Second Page 页面销毁时获取的返回结果 result =  $value'); });
    

    相关文章

      网友评论

          本文标题:Flutter路由

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