Flutter路由和导航

管理多个页面时有两个核心概念和类:Route 和 Navigator。 一个Route是一个屏幕或页面的抽象,Navigator是管理Route的Widget。Navigator能够经过route入栈和出栈来实现页面之间的跳转。ios

一、Route

Route 一个页面要想被路由统一管理,必须包装为一个Route。 Route是一个抽象类,进入Route类,点击cmd+opt+B查看其实现类。 bash

imag01.png

/**
 * 使用 MaterialPageRoute
 * Android: 从屏幕底部滑动到顶部
 * iOS:     从屏幕右侧滑动到左侧
 */
Navigator.of(context).push(MaterialPageRoute(builder: (ctx) {
  return FirstPage("a home message---first");
}));

/**
 * 使用PageRouteBuilder渐变效果
 */
Navigator.of(context).push(PageRouteBuilder(pageBuilder: (ctx, anim1, anim2) {
  return FadeTransition(
      opacity: anim1, child: FirstPage("a home message----first"));
}));
                     
复制代码

二、Navigator

Navigator:管理全部的Route的Widget,经过一个Stack来进行管理的。app

// 路由跳转:传入一个路由对象
Future<T> push<T extendsObject>(Route<T> route)

// 路由跳转:传入一个名称(命名路由)
Future<T> pushNamed<T extendsObject>(
  String routeName, {
    Object arguments,
  })

// 路由返回:能够传入一个参数
bool pop<T extendsObject>([ T result ])
复制代码
  • 实现从一个页面跳转到FirstPage页面并实现相互传值。
Future result=Navigator.of(context).push(MaterialPageRoute(builder: (ctx) {
  return FirstPage("first params");
}));

result.then((value){
  print("pop 返回---$value");
});
复制代码
import 'package:flutter/material.dart';

class FirstPage extends StatelessWidget {
 static const routeName="/firstPage";
 final String _message;

  FirstPage(this._message);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("first page"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(_message, style: TextStyle(fontSize: 20),),
            RaisedButton(
              child: Text("first pop"),
              onPressed: () {
                Navigator.of(context).pop("first pop");
              },
            ),
          ],
        ),
      ),
    );
  }
}

复制代码
  • 经过命名路由实现跳转到SecondPage,先要在入口配置路由。
class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter widget',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      routes: {
       //命名路由
        SecondPage.routeName:(context)=>SecondPage(),
        ThirdPage.routeName: (context) => ThirdPage(),
      },
      //因为FirstPage已经建立了构造器
      onGenerateRoute: (settings){
        if (settings.name == FirstPage.routeName) {
          return MaterialPageRoute(
              builder: (context) {
                return FirstPage(settings.arguments);
              }
          );
        }
        return null;
      },
      //未知路由
      onUnknownRoute: (settings){
        return MaterialPageRoute(
          builder: (context){
            return UnKnownPage();
          }
        );
      },
      home: MyHomePage(),
    );
  }
}
复制代码
Navigator.of(context).pushNamed(SecondPage.routeName, arguments: "a home message-03");
复制代码

SecondPage代码,里面获取参数less

import 'package:flutter/material.dart';

class SecondPage extends StatelessWidget {
  static const routeName="/secondPage";

  @override
  Widget build(BuildContext context) {
    final _message = ModalRoute.of(context).settings.arguments as String;
    return Scaffold(
      appBar: AppBar(
        title: Text("second page"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(_message, style: TextStyle(fontSize: 20),),
            RaisedButton(
              child: Text("second pop"),
              onPressed: () {
                Navigator.of(context).pop("second pop");
              },
            ),
          ],
        ),
      ),
    );
  }
}

复制代码
  • 监听页面的返回按钮的两种方式
appBar: AppBar(
  title: Text("third page"),
  leading: IconButton(
    icon: Icon(Icons.arrow_back_ios),
    onPressed: () {
      Navigator.of(context).pop("third page back");
    },
  ),
),
复制代码
import 'package:flutter/material.dart';

class ThirdPage extends StatelessWidget {
  static const routeName = "/thirdPage";

  @override
  Widget build(BuildContext context) {
    final _message = ModalRoute.of(context).settings.arguments as String;
    return WillPopScope(
      onWillPop: () {
        // 当返回为true时,flutter自动帮助咱们执行返回操做
        // 当返回为false时, 自行写返回代码
        Navigator.of(context).pop("third page back");
        return Future.value(false);
      },
      child: Scaffold(
        appBar: AppBar(
          title: Text("third page"),
//          leading: IconButton(
//            icon: Icon(Icons.arrow_back_ios),
//            onPressed: () {
//              Navigator.of(context).pop("third pop");
//            },
//          ),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(
                _message,
                style: TextStyle(fontSize: 20),
              ),
              RaisedButton(
                child: Text("third pop"),
                onPressed: () {
                  Navigator.of(context).pop("third page back");
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
}

复制代码
相关文章
相关标签/搜索