1. 程式人生 > 其它 >Navigator中命名路由使用中的問題

Navigator中命名路由使用中的問題

技術標籤:flutter

文章目錄

一、前言

在使用Navigator命名路由時候,子頁面不能用MaterialApp進行包裹,否則該頁面無法使用Navigator.of(context).pushNamed("/page2");進行跳轉。但是其它頁面可以使用MaterialApp進行包裹,子頁面也可以使用普通的路由方式進行跳轉,普通方式如下:

   Navigator.push(context, MaterialPageRoute(
                      builder: (BuildContext context){
                        return Page2();
                      }
                  ));

如果跟頁面使用了MaterialApp進行包裹,在根頁面進行跳轉到其他頁面時候也使用了命名路由,則會觸發以下錯誤:

Could not find a generator for route RouteSettings("/page2", null) in the _WidgetsAppState.

Make sure your root app widget has provided a way to generate 
this route.
Generators for routes are searched for in the following order:
 1. For the "/" route, the "home" property, if non-null, is used.
 2. Otherwise, the "routes" table is used, if it has an entry for the route.
 3. Otherwise, onGenerateRoute is called. It should return a non-null value for any valid route not handled by "home" and "routes".
 4. Finally if all else fails onUnknownRoute is called.
Unfortunately, onUnknownRoute was not set.
When the exception was thrown, this was the stack: 
#0      _WidgetsAppState._onUnknownRoute.<anonymous closure> (package:flutter/src/widgets/app.dart:1175:9)
#1      _WidgetsAppState._onUnknownRoute (package:flutter/src/widgets/app.dart:1190:6)
#2      NavigatorState._routeNamed (package:flutter/src/widgets/navigator.dart:3388:36)
#3      NavigatorState.pushNamed (package:flutter/src/widgets/navigator.dart:3425:20)
#4      Page1.build.<anonymous closure>.<anonymous closure> (package:flutter_dq_app/test/navigator/page1.dart:20:45)
...
Handler: "onTap"
Recognizer: TapGestureRecognizer#b4811
  debugOwner: GestureDetector
  state: possible
  won arena
  finalPosition: Offset(184.7, 438.2)
  finalLocalPosition: Offset(39.4, 26.9)
  button: 1
  sent tap down

二、命名路由的程式碼簡單程式碼演示

Routers.dart路由管理

import 'package:flutter_dq_app/test/navigator/page1.dart';
import 'package:flutter_dq_app/test/navigator/page2.dart';
import 'package:flutter_dq_app/test/navigator/page3.dart';
class Routers{
  static String root = "/";//跟頁面必須定義為這個樣式
  static String page2 = "/page2";
  static String page3 = "/page3";
  static final routers = {
    root: (context) => Page1(),
    page2: (context) => Page2(),
    page3: (context) => Page3(),
  };
  // static onGenerateRoute(RouteSettings settings) {
  //   //統一處理
  //   final String name = settings.name;
  //   print('YM------>路由名字:$name');
  //   final Function pageContentBuilder = routers[name];
  //   if (pageContentBuilder != null) {
  //     if (settings.arguments != null) {
  //       final Route route = MaterialPageRoute(
  //           builder: (context) =>
  //               pageContentBuilder(context, arguments: settings.arguments));
  //       return route;
  //     } else {
  //       final Route route =
  //       MaterialPageRoute(builder: (context) => pageContentBuilder(context));
  //       return route;
  //     }
  //   }
  // }
}

main.dart首頁

import 'package:flutter/material.dart';
import 'package:flutter_dq_app/test/navigator/routers.dart';
void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Material App',
      initialRoute: "/",
      routes: Routers.routers,
      // onGenerateRoute: (settings)=>Routers.onGenerateRoute(settings),//該程式碼解開註釋也可以使用
    );
  }
}

page1.dart

import 'package:flutter/material.dart';
import 'package:flutter_dq_app/test/navigator/routers.dart';
void main() => runApp(Page1());

class Page1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Material App Bar'),
      ),
      body: Center(
        child: Container(
          child: Builder(
              builder: (BuildContext context){
                return RaisedButton(
                  onPressed: (){
                    Navigator.of(context).pushNamed(Routers.page2);
                  },
                  child: Text('第一個頁面'),
                );
              }
          ),
        ),
      ),
    );
  }
}

page2.dart

import 'package:flutter/material.dart';
import 'package:flutter_dq_app/test/navigator/routers.dart';
void main() => runApp(Page2());

class Page2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Material App Bar'),
      ),
      body: Center(
        child: Container(
          child: Builder(
            builder: (BuildContext context){
              return RaisedButton(
                onPressed: (){
                  Navigator.of(context).pushNamed(Routers.page3);
                },
                child: Text('第二個頁面'),
              );
            },
          ),
        ),
      ),
    );
  }
}

page3.dart

import 'package:flutter/material.dart';
import 'package:flutter_dq_app/test/navigator/routers.dart';
void main() => runApp(Page3());

class Page3 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Material App Bar'),
      ),
      body: Center(
        child: Container(
            child: Builder(
              builder: (BuildContext context){
                return RaisedButton(
                  onPressed: (){
                    Navigator.of(context).popUntil(ModalRoute.withName(Routers.root));
                  },
                  child: Text('第三個頁面'),
                );
              },
            )
        ),
      ),
    );
  }
}