IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Flutter入门-路由与导航<一> -> 正文阅读

[移动开发]Flutter入门-路由与导航<一>

上一篇在学习MaterialApp的时候,就初步学习了一下路由,这篇就单独深入学习一下路由与导航的内容,以及学习Navigator2.0的内容。

Navigator1.0

一、跳转页面(push入栈)

///直接入栈
static Future<T?> push<T extends Object?>(BuildContext context, Route<T> route);
static Future<T?> pushNamed<T extends Object?>(
    BuildContext context,
    String routeName, {
    Object? arguments,
  })
  
///替换入栈
static Future<T?> pushReplacement<T extends Object?, TO extends Object?>(BuildContext context, Route<T> newRoute, { TO? result })
static Future<T?> pushReplacementNamed<T extends Object?, TO extends Object?>(
    BuildContext context,
    String routeName, {
    TO? result,
    Object? arguments,
  })
  
///过滤条件移除入栈
static Future<T?> pushAndRemoveUntil<T extends Object?>(BuildContext context, Route<T> newRoute, RoutePredicate predicate)
static Future<T?> pushNamedAndRemoveUntil<T extends Object?>(
    BuildContext context,
    String newRouteName,
    RoutePredicate predicate, {
    Object? arguments,
  })

从定义的方法中可以看出,Navigator1.0中,很多文章习惯性将导航大致可以分为两类,一类是静态的(命名的),一类是动态的;静态导航需要和routes路由搭配使用。但是我更喜欢从行为上来区分,直接入栈和替换入栈很好理解,我们着重理解一下过滤条件的移除入栈这种行为。

pushAndRemoveUntil<T extends Object?>(BuildContext context, Route newRoute, RoutePredicate predicate)

会按次序移除其他的路由,直到遇到被标记的路由(predicate函数返回了true)时停止。若 没有标记的路由,则移除全部。
PS:先执行的Remove,然后再Push
在这里插入图片描述
three_page.dart

ModalRoute.withName(‘/’):该逻辑会去匹配根页面,也就是我们的home_page

如果想使用动态导航,并且还可以给页面起个名字,可以使用MaterialPageRoute里面的settings属性(RouteSettings(name: ‘name’)),首页通常可以使用’/'匹配。

import 'package:flutter/material.dart';
import 'package:flutter_hello/home_page.dart';
import 'package:flutter_hello/second_page.dart';

class MyThreePage extends StatelessWidget {
  const MyThreePage({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          leading: BackButton(
            onPressed: () {
              Navigator.pop(context);
            },
          ),
        ),
        body: Center(
          child: MaterialButton(
            onPressed: () {
              Navigator.pushAndRemoveUntil(
                  context,MaterialPageRoute(builder: (context) => SecondPage()),ModalRoute.withName('/'));
            },
            child: const Text('第三个页面,跳转到首页'),
          ),
        ),
      ),
    );
  }
}

pushNamedAndRemoveUntil<T extends Object?>( BuildContext context,String newRouteName,RoutePredicate predicate, {Object? arguments,})

home_page.dart

import 'package:flutter/material.dart';



class HomePage extends StatelessWidget with RouteAware{
  const HomePage({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: MaterialButton(
              onPressed: () {
                Navigator.pushNamed(context, "second");
              },
              child: const Text(
                '下一页',
                style: TextStyle(color: Colors.redAccent),
              )),
        ),
      ),
    );
  }
}

second_page.dart

import 'package:flutter/material.dart';

class SecondPage extends StatelessWidget {
  const SecondPage({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('第二个页面'),
          centerTitle: true,
          leading: BackButton(
            onPressed: () {
              Navigator.pop(context);
            },
          ),
        ),
        body: Center(
          child: MaterialButton(
            onPressed: () {
              Navigator.pushNamed(context, "three");
            },
            child: const Text('第二个页面'),
          ),
        ),
      ),
    );
  }
}

three_page.dart

import 'package:flutter/material.dart';
import 'package:flutter_hello/home_page.dart';
import 'package:flutter_hello/second_page.dart';

class MyThreePage extends StatelessWidget {
  const MyThreePage({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          leading: BackButton(
            onPressed: () {
              Navigator.pop(context);
            },
          ),
        ),
        body: Center(
          child: MaterialButton(
            onPressed: () {
              Navigator.pushAndRemoveUntil(
                  context,MaterialPageRoute(builder: (context) => SecondPage()),(Route router) => router.settings.name == "home");
            },
            child: const Text('第三个页面,跳转到第二页'),
          ),
        ),
      ),
    );
  }
}

由于之前的页面都是通过命名路由跳转的,所以每个页面都可以用名称作为标识

1、目前堆栈顺序:home_page -> second_page->three_page
2、three_page通过pushAndRemoveUntil进入到second_page后的栈顺序:
home_page -> second_page

二、页面返回(pop出栈)

///直接出栈返回
pop<T extends Object?>(BuildContext context, [ T? result ]

///出栈后再压入新的页面入栈
popAndPushNamed<T extends Object?, TO extends Object?>(
    BuildContext context,
    String routeName, {
    TO? result,
    Object? arguments,
  }) 

///直到符合predicate,才会停止出栈操作
popUntil(BuildContext context, RoutePredicate predicate)

1、pop(直接出栈)

在这里插入图片描述

2、popAndPushNamed(当前页面出栈,然后再压入新的页面入栈)

在这里插入图片描述

3、popUntil(出栈、出栈、匹配到predicate,则停止出栈)

在这里插入图片描述

三、传参

3-1、入栈传参(跳转页面携带数据)

Arguments.dart
自定义的参数类

class Arguments {
  String _name = "";
  int _age = 0;

  String get name => _name;

  set name(String value) {
    _name = value;
  }

  int get age => _age;

  set age(int value) {
    _age = value;
  }
}

3-1-1、动态导航传参

使用MaterialPageRoute中的settings属性传递

                Arguments arguments = Arguments();
                arguments.name = "我是从上个页面传的";
                arguments.age = 18;
                Navigator.push(
                    context,
                    MaterialPageRoute(
                        builder: (context) => SecondPage(),
                        settings: RouteSettings(name: 'second', arguments: arguments)));

3-1-2、命名路由传参

使用arguments属性传递

                Arguments arguments = Arguments();
                arguments.name = "我是从上个页面传的";
                arguments.age = 18;
                Navigator.pushNamed(context, "second", arguments: _arguments);

3-1-3、目标页面参数的接收

Arguments arguments=ModalRoute.of(context)?.settings.arguments as Arguments;

1、使用ModalRoute.of(context)?.settings.arguments获取
2、使用as强转为相关对象

3-2、出栈传参(返回页面携带数据)

3-2-1、pop<T extends Object?>(BuildContext context, [ T? result ])出栈传参

通过泛型T,携带出栈时携带的参数

              Arguments result = Arguments();
              result.name = "我是来源于第二个页面的数据";
              Navigator.pop(context, result);

3-2-2、返回的目标页通过then接收处理参数

我们回头看一下导航入栈跳转页面的函数的返回值都是Future类型,也就是异步,接收返回页面的数据就是通过这个异步处理的。

在这里插入图片描述

Navigator.push(
          context,
          MaterialPageRoute(
                builder: (context) => SecondPage(),
                settings: RouteSettings(name: 'second', arguments: arguments)))
         .then((value){
             result=value as Arguments;
             setState((){});
                });
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-10-22 21:26:57  更:2022-10-22 21:31:07 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/20 0:16:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码