flutter07 - Routing

Open a new route

TipRoute create a route that takes a parameter prompt text, it is responsible for incoming text displayed on the page, in addition TipRoute we add a "back" button, click on the return of a route at the same time will bring a return parameter

import 'package:flutter/material.dart'; //导包

//应用入口
void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '我是标题',
      theme: ThemeData(
        primarySwatch: Colors.blue,//蓝色主题
      ),
      home: MyHomePage(title: '我是HomePager标题名字'),
    );
  }
}

//首页,继承自有状态组件
class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              '点击进行累加~',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
            FlatButton(
              child: Text("打开新的路由"),
              textColor: Colors.blue,
              onPressed: (){
                //导航到新的路由
                Navigator.push(context,MaterialPageRoute(builder: (context){
                  return NewRoute();
                }));
              },
            ),
            FlatButton(
              child: Text("打开新的路由2"),
              textColor: Colors.amber,
              onPressed: (){
                //导航到第二个路由
                Navigator.push(context, MaterialPageRoute(builder: (context){
                  return NewRoute2();

                }));
              },
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

class NewRoute extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.green,
        title: Text("new Route"),
      ),
      body: Center(
        child: Text("This is new Route"),
      ),
    );
  }
}

class NewRoute2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.red,
        title: Text("第二个页面"),
      ),
      body: Center(
        child: Text("第二个页面的内容"),
      ),
    );
  }
}

MaterialPageRoute

  MaterialPageRoute({
    WidgetBuilder builder,
    RouteSettings settings,
    bool maintainState = true,
    bool fullscreenDialog = false,
  })
  • builderWidgetBuilder type is a callback function, its role is to route pages to build specific content, the return value is a widget. We usually want to achieve this callback returns an instance of the new route.
  • settings Contains routing configuration information, such as the route name, if the initial routing (Home).
  • maintainState: By default, when a new routing stack, the original route will still be kept in memory, if you want to release all the resources it occupied at the time of routing useless, it can be set maintainStateto false.
  • fullscreenDialogIt indicates whether the page is a new route fullscreen modal dialog, in iOS, if fullscreenDialogis true, a new page will be slid from the bottom of the screen (rather than horizontal).

Navigator

Two methods:

Future push(BuildContext context, Route route)

Given routing stack (i.e., open a new page), the return value is a Futuretarget, returns a new route for receiving data stack (i.e., closed).

bool pop(BuildContext context, [ result ])

Given routing stack (i.e., open a new page), the return value is a Futuretarget, returns a new route for receiving data stack (i.e., closed).

Navigator routing the order of execution is looking initialRoute -> onGenerateRoute -> onUnknownRoute

Given routing stack (i.e., open a new page), the return value is a Futuretarget, returns a new route for receiving data stack (i.e., closed).

Navigator.push(BuildContext context, Route route)等价于Navigator.of(context).push(Route route)

Route by value

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "页面1",
      theme: ThemeData(
        primarySwatch: Colors.red,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text("页面1"),
        ),
        body: GiveRoute(),
      ),
    );
  }
}

class GiveRoute extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: RaisedButton(
        onPressed: () async {
          //打开新页面,并且等待返回结果
          var result = await Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) {
                return TipRoute(
                  text: "我是传递给TipRoute的文本",
                );
              },
            ),
          );
          print("路由的返回数据为$result");
        },
        child: Text("打开提示页面"),
      ),
    );
  }
}

/**
 * 返回数据的
 */
class TipRoute extends StatelessWidget {
  final String text;

  TipRoute({Key key, @required this.text}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("提示信息"),
      ),
      body: Padding(
        padding: EdgeInsets.all(18),
        child: Column(
          children: <Widget>[
            Text(text),
            RaisedButton(
              onPressed: () => Navigator.pop(context, "我是返回值"),
              child: Text("返回"),
            ),
          ],
        ),
      ),
    );
  }
}

By constructing the second function value to a pass Route

The second Route by Navigator.pop (context, "I am the return value"), return to the traditional values ​​of a Route

Route first receive by the following code

 return Center(
      child: RaisedButton(
        onPressed: () async {
          //打开新页面,并且等待返回结果
          var result = await Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) {
                return TipRoute(
                  text: "我是传递给TipRoute的文本",
                );
              },
            ),
          );
          print("路由的返回数据为$result");
        },
        child: Text("打开提示页面"),
      ),
    );

Named routes

"Named Route" (Named Route) that is the name of the route

Routing Table

To use named routes, we must first register and provide a routing table (routing table), so the application knows which name corresponds to which routing component. In fact, the routing table is registered to route a name, define the routing table is as follows:

Map<String, WidgetBuilder> routes;

It is a Map, key name for the route, which is a string; value is a buildercallback function for generating a corresponding routing widget.

The routing lookup in the routing table name corresponding to WidgetBuilderthe callback function, and then calls the callback function generation widget and return routes.

Use named routes

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "路由表 - 命名路由",
      theme: ThemeData(
        primarySwatch: Colors.amber,
      ),
      routes: {
        "/": (context) => HomeDemo(title: "主页"), //使用命名路由 注册首页路由
        "new_page1": (context) => PageRoutes1(),
        "new_page2": (context) => PageRoutes2(),
      },
    );
  }
}

class HomeDemo extends StatelessWidget {
  String title;

  HomeDemo({Key key, @required this.title}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("主页"),
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            RaisedButton(
              onPressed: () {
                Navigator.pushNamed(context, "new_page1");
              },
              child: Text("通过命名路由方式跳转到page1"),
            ),
            RaisedButton(
              onPressed: () {
                Navigator.pushNamed(context, "new_page2");
              },
              child: Text("通过命名路由方式跳转到page2"),
            ),
          ],
        ),
      ),
    );
  }
}

class PageRoutes1 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("页面一"),
      ),
    );
  }
}

class PageRoutes2 extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("页面二"),
      ),
    );
  }
}

By naming Routing Registry Home

routes: {
  "/": (context) => HomeDemo(title: "主页"), //使用命名路由 注册首页路由
  "new_page1": (context) => PageRoutes1(),
  "new_page2": (context) => PageRoutes2(),
},

Named routes pass parameters

import 'package:first_flutter_app/main.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "命名路由传递参数",
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      routes: {
        "/": (context) => HomeDemo(),
        "newpage": (context) => NewPageRoute(),
      },
    );
  }
}

class HomeDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("命名路由传递参数"),
        backgroundColor: Colors.amberAccent,
      ),
      body: Center(
        child: RaisedButton(
          onPressed: () {
            Navigator.of(context).pushNamed("newpage", arguments: "项目ID1234");
          },
          child: Text("命名路由 传递函数"),
        ),
      ),
    );
  }
}

class NewPageRoute extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

    var args = ModalRoute.of(context).settings.arguments;

    return Scaffold(
      appBar: AppBar(
        title: Text("NewPageRoute"),
        backgroundColor: Colors.amberAccent,
      ),
      body: Center(
        child: Text("命名路由接受到的参数:$args"),
      ),
    );
  }
}

There are no naming and routing structure constructed

import 'package:first_flutter_app/main.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "命名路由传递参数",
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      routes: {
        "/": (context) => HomeDemo(),
        "newpage": (context) => NewPageRoute(), //无构造的
        "tiproute": (context) =>
            TipRoute(text: ModalRoute.of(context).settings.arguments), //有构造的
      },
    );
  }
}

class HomeDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("命名路由传递参数"),
        backgroundColor: Colors.amberAccent,
      ),
      body: Center(
        child: Column(
          children: <Widget>[
            RaisedButton(
              onPressed: () {
                Navigator.of(context)
                    .pushNamed("newpage", arguments: "项目ID1234");
              },
              child: Text("命名路由无构造的 传递函数"),
            ),
            RaisedButton(
              onPressed: () {
                Navigator.of(context)
                    .pushNamed("tiproute", arguments: "你好,我是flutter命名函数传值");
              },
              child: Text("命名路由有构造的 传递函数"),
            )
          ],
        ),
      ),
    );
  }
}

/**
 * 无构造的
 */
class NewPageRoute extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    var args = ModalRoute.of(context).settings.arguments;//本行是接受参数

    return Scaffold(
      appBar: AppBar(
        title: Text("NewPageRoute"),
        backgroundColor: Colors.amberAccent,
      ),
      body: Center(
        child: Text("命名路由接受到的参数:$args"),
      ),
    );
  }
}

/**
 * 有构造的
 */
class TipRoute extends StatelessWidget {
  final String text; //用来接受传过来的信息

  TipRoute({Key key, @required this.text}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("提示信息"),
      ),
      body: Padding(
        padding: EdgeInsets.all(18),
        child: Column(
          children: <Widget>[
            Text(text),
            RaisedButton(
              onPressed: () => Navigator.pop(context, "我是返回值"),
              child: Text("返回"),
            ),
          ],
        ),
      ),
    );
  }
}

Route generation hook

By onGenerateRoute()function parameter extraction, and pass parameters to the component

Development of a electricity supplier APP, when the user is not logged in can see the information of the store, merchandise, etc., but after the transaction, shopping cart, user's personal information and other pages need to be logged in to watch. In order to achieve the above functions, we need to determine the user logs in the open state before routing each page! If every route open before we all need to determine what will be very troublesome.

MaterialApp have a onGenerateRoute property, it may be called upon to open a named route,

The reason why is possible because when you call Navigator.pushNamed (...) to open a named route if the specified route name is already registered in the routing table, routing table builder will function to generate routing component call; if the routing table not registered, it will call onGenerateRoute to generate routes.

onGenerateRouteSignature callback as follows:

Route<dynamic> Function(RouteSettings settings)
MaterialApp(
  ... //省略无关代码
  onGenerateRoute:(RouteSettings settings){
      return MaterialPageRoute(builder: (context){
           String routeName = settings.name;
       // 如果访问的路由页需要登录,但当前未登录,则直接返回登录页路由,
       // 引导用户登录;其它情况则正常打开路由。
     }
   );
  }
);
Published 49 original articles · won praise 6 · views 80000 +

Guess you like

Origin blog.csdn.net/zlhyy666666/article/details/104887105
Recommended