Flutter之路由和导航

目录:

    • 1、flutter路由和导航简介
    • 2、路由的使用
      • 2.1、使用 Navigator
      • 2.2、使用命名路由
      • 2.3、使用路由器
    • 3、应用中添加Tab导航
    • 4、页面跳转一个新页面和回退
    • 5、传递数据到新页面
    • 6、使用 RouteSettings 传递参数

1、flutter路由和导航简介

Flutter 提供了一个完整的系统,用于在屏幕之间导航和处理 深层链接。没有复杂深度链接的小型应用程序可以使用 Navigator,而具有特定深度链接和导航的应用程序 要求还应该使用 Router 来正确处理 Android 和 iOS,并在应用程序运行时与地址栏保持同步 在 Web 上运行。

2、路由的使用

2.1、使用 Navigator

小组件使用正确的过渡将屏幕显示为堆栈 动画。要导航到新屏幕,请通过 route 访问 并调用命令式方法。

child: const Text('Open second screen'),
onPressed: () {Navigator.of(context).push(MaterialPageRoute(builder: (context) => const SecondScreen()),);
},

因为会保留一堆对象(表示历史记录 stack),该方法还接受一个 object。

2.2、使用命名路由

child: const Text('Open second screen'),
onPressed: () {Navigator.pushNamed(context, '/second');
},

/second表示在列表中声明的命名路由。有关完整示例,请按照 Flutter 说明书中的使用命名路由导航 recipe 进行作。MaterialApp.routes

局限性:

  • 尽管命名路由可以处理深度链接,但行为始终相同,并且 无法自定义。当平台收到新的深度链接时,Flutter 将新用户推送到Navigator 上,而不管用户当前位于何处。
  • Flutter 也不支持使用 命名路由。由于这些原因,我们不建议在大多数 应用。

2.3、使用路由器

具有高级导航和路由要求(例如 使用指向每个屏幕的直接链接的 Web 应用程序,或具有多个小组件的应用程序)应使用路由包,例如 go_router 解析路由路径并配置每当应用程序收到 new deep link 的 intent 值。

要使用 Router,请切换到 or 上的构造函数,并为其提供一个配置。路由包, 如 go_router,通常提供路由配置和路由 可以按如下方式使用:

child: const Text('Open second screen'),
onPressed: () => context.go('/second'),

因为像 go_router 这样的包是声明性的,所以它们将始终显示 收到深度链接时的相同屏幕。

go_router的使用案例:
在这里插入图片描述

dependencies:flutter:sdk: fluttergo_router: ^x.y.z  # 替换x.y.z为最新版本号

在这里插入图片描述

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';void main() {runApp(MyApp());
}class MyApp extends StatelessWidget {Widget build(BuildContext context) {final _router = GoRouter(initialLocation: '/',routes: [GoRoute(path: '/',builder: (context, state) => HomePage(),),GoRoute(path: '/details',builder: (context, state) => DetailsPage(),),],);return MaterialApp.router(routerConfig: _router,);}
}
  1. 创建页面和导航
    确保你已创建了相应的页面(如HomePage和DetailsPage),这些将作为路由的目标。例如:
class HomePage extends StatelessWidget {Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text('Home')),body: Center(child: ElevatedButton(onPressed: () {context.go('/details'); // 使用context.go进行导航},child: Text('Go to Details'),),),);}
}
  1. 使用参数和嵌套路由(可选)
    你可以在路由中使用参数,并设置嵌套路由:
GoRoute(path: '/user/:id', // 参数使用冒号标记builder: (context, state) {final userId = state.params['id']; // 获取参数值return UserPage(userId: userId); // 将参数传递给页面},routes: [ // 嵌套路由示例GoRoute(path: 'profile', builder: (context, state) => ProfilePage(), ),],
),

在页面中使用参数:

class UserPage extends StatelessWidget {final String userId; // 页面接收参数构造函数或初始化列表赋值方式之一// 构造函数接收参数userId 初始化列表赋值方式也行 如 final String userId; UserPage({Key? key, required this.userId}) : super(key: key); 然后在build中使用userId。 例如显示在文本中:Text('User ID: $userId')。 嵌套路由的使用同理,你可以在ProfilePage中通过context访问嵌套路由的参数。 例如:final profileId = state.params['profileId']; // 在ProfilePage的build方法中使用。 注意这里的state是从context获取的,通常在build方法中通过ModalRoute.of(context).settings来获取。 但由于我们使用了GoRouter,可以直接通过builder的state参数获取。 例如在ProfilePage的build方法中可以直接使用String profileId = state.params['profileId']; 来获取参数。 若要导航到嵌套路由,可以使用context.go('/user/${userId}/profile');。 若要在嵌套路由的页面中使用非嵌套路由的参数,可以通过ModalRoute.of(context).settings.arguments来获取。 但由于我们使用了GoRouter,可以直接通过state参数获取。 若要在嵌套路由中导航,可以使用context.go('profile');(注意没有前导斜杠)。 若要在非嵌套路由中使用嵌套路由的参数,可以在非嵌套路由的页面中通过context.go('/user/${userId}'); 然后在这个路由的builder方法中通过state.subloc获取嵌套路由的状态,例如:StringUserPage({required this.userId}); 

3、应用中添加Tab导航

在这里插入图片描述

import 'package:flutter/material.dart';void main() {runApp(const TabBarDemo());
}class TabBarDemo extends StatelessWidget {const TabBarDemo({super.key});Widget build(BuildContext context) {return MaterialApp(home: DefaultTabController(length: 3,child: Scaffold(appBar: AppBar(bottom: const TabBar(tabs: [Tab(icon: Icon(Icons.directions_car)),Tab(icon: Icon(Icons.directions_transit)),Tab(icon: Icon(Icons.directions_bike)),],),title: const Text('Tabs Demo'),),body: const TabBarView(children: [Icon(Icons.directions_car),Icon(Icons.directions_transit),Icon(Icons.directions_bike),],),),),);}
}

4、页面跳转一个新页面和回退

  • 用 Navigator.push() 跳转到第二个路由
  • 用 Navigator.pop() 回退到第一个路由

5、传递数据到新页面

在这里插入图片描述
在这里插入图片描述

import 'package:flutter/material.dart';class Todo {final String title;final String description;const Todo(this.title, this.description);
}void main() {runApp(MaterialApp(title: 'Passing Data',home: TodosScreen(todos: List.generate(20,(i) => Todo('Todo $i','A description of what needs to be done for Todo $i',),),),),);
}class TodosScreen extends StatelessWidget {const TodosScreen({super.key, required this.todos});final List<Todo> todos;Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('Todos')),body: ListView.builder(itemCount: todos.length,itemBuilder: (context, index) {return ListTile(title: Text(todos[index].title),// When a user taps the ListTile, navigate to the DetailScreen.// Notice that you're not only creating a DetailScreen, you're// also passing the current todo through to it.onTap: () {Navigator.push(context,MaterialPageRoute(builder: (context) => DetailScreen(todo: todos[index]),),);},);},),);}
}class DetailScreen extends StatelessWidget {// In the constructor, require a Todo.const DetailScreen({super.key, required this.todo});// Declare a field that holds the Todo.final Todo todo;Widget build(BuildContext context) {// Use the Todo to create the UI.return Scaffold(appBar: AppBar(title: Text(todo.title)),body: Padding(padding: const EdgeInsets.all(16),child: Text(todo.description),),);}
}

6、使用 RouteSettings 传递参数

import 'package:flutter/material.dart';class Todo {final String title;final String description;const Todo(this.title, this.description);
}void main() {runApp(MaterialApp(title: 'Passing Data',home: TodosScreen(todos: List.generate(20,(i) => Todo('Todo $i','A description of what needs to be done for Todo $i',),),),),);
}class TodosScreen extends StatelessWidget {const TodosScreen({super.key, required this.todos});final List<Todo> todos;Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('Todos')),body: ListView.builder(itemCount: todos.length,itemBuilder: (context, index) {return ListTile(title: Text(todos[index].title),// When a user taps the ListTile, navigate to the DetailScreen.// Notice that you're not only creating a DetailScreen, you're// also passing the current todo through to it.onTap: () {Navigator.push(context,MaterialPageRoute(builder: (context) => const DetailScreen(),// Pass the arguments as part of the RouteSettings. The// DetailScreen reads the arguments from these settings.//通过此处来传递参数,其他地方同上settings: RouteSettings(arguments: todos[index]),),);},);},),);}
}class DetailScreen extends StatelessWidget {const DetailScreen({super.key});Widget build(BuildContext context) {final todo = ModalRoute.of(context)!.settings.arguments as Todo;// Use the Todo to create the UI.return Scaffold(appBar: AppBar(title: Text(todo.title)),body: Padding(padding: const EdgeInsets.all(16),child: Text(todo.description),),);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/80322.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

KMS工作原理及其安全性分析

在当今数字化时代&#xff0c;数据安全已经成为企业和个人最为关注的话题之一。随着云计算和大数据的快速发展&#xff0c;如何安全地管理密钥成为了一个重要的挑战。KMS&#xff08;Key Management Service&#xff0c;密钥管理服务&#xff09;作为一种专业的密钥管理解决方案…

机器学习在网络安全中的应用:守护数字世界的防线

一、引言 随着信息技术的飞速发展&#xff0c;网络安全问题日益凸显&#xff0c;成为全球关注的焦点。传统的网络安全防护手段&#xff0c;如防火墙、入侵检测系统&#xff08;IDS&#xff09;和防病毒软件&#xff0c;虽然在一定程度上能够抵御攻击&#xff0c;但在面对复杂多…

Java在excel中导出动态曲线图DEMO

1、环境 JDK8 POI 5.2.3 Springboot2.7 2、DEMO pom <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.3</version></dependency><dependency><groupId>commons…

Android APP 爬虫操作

工具 夜神模拟器、charles、mitm 等 mitm的使用参考:Mitmproxy对Android进行抓包&#xff08;真机&#xff09;_mitmproxy 安卓-CSDN博客 charles的使用参考&#xff1a;【全网最详细】手把手教学Charles抓包工具详细自学教程&#xff0c;完整版安装教程&#xff0c;详细介绍…

Redis的LFU策略具体怎么工作?

Redis的LFU&#xff08;Least Frequently Used&#xff09;策略通过动态跟踪键的访问频率实现淘汰决策&#xff0c;其核心工作逻辑可分为以下四个部分&#xff1a; 数据结构设计‌ 字段拆分‌&#xff1a;每个Redis对象&#xff08;redisObject&#xff09;的lru字段&#xff…

Redis 及其在系统设计中的作用

什么是Redis Redis 是一个开源的内存数据结构存储系统&#xff0c;可用作数据库、缓存和消息代理。它因其快速的性能、灵活性和易用性而得到广泛应用。 Redis 数据存储类型 Redis 允许开发人员以各种数据结构&#xff08;例如字符串、位图、位域、哈希、列表、集合、有序集合…

MySQL:如何用关系型数据库征服NoSQL核心战场?

写在前面&#xff1a;当SQL遇见NoSQL的十年之变 2012年MongoDB掀起文档数据库革命时&#xff0c;开发者们不得不在灵活性与事务一致性之间做痛苦抉择。十年后的今天&#xff0c;MySQL 8.0的JSON功能已实现&#xff1a; ✅ 二进制存储效率超越传统BLOB 40% ✅ 多值索引使JSON查…

Dart Flutter数据类型详解 int double String bool list Map

目录 字符串的几种方式 bool值的判断 List的定义方式 Map的定义方式 Dart判断数据类型 (is 关键词来判断类型) Dart的数据类型详解 int double String bool list Map 常用数据类型: Numbers(数值): int double Strings(字符串) String Booleans(布尔…

win11中wsl在自定义位置安装ubuntu20.04 + ROS Noetic

wsl的安装 环境自定义位置安装指定ubuntu版本VsCodeROS备份与重载备份重新导入 常用命令参考文章 环境 搜索 启用或关闭 Windows 功能 勾选这2个功能&#xff0c;然后重启 自定义位置安装指定ubuntu版本 从网上找到你所需要的相关wsl ubuntu版本的安装包&#xff0c;一般直…

得物业务参数配置中心架构综述

一、背景 现状与痛点 在目前互联网飞速发展的今天&#xff0c;企业对用人的要求越来越高&#xff0c;尤其是后端的开发同学大部分精力都要投入在对复杂需求的处理&#xff0c;以及代码架构&#xff0c;稳定性的工作中&#xff0c;在对比下&#xff0c;简单且重复的CRUD就显得…

Nginx 二进制部署与 Docker 部署深度对比

一、核心概念解析 1. 二进制部署 通过包管理器&#xff08;如 apt/yum&#xff09;或源码编译安装 Nginx&#xff0c;直接运行在宿主机上。其特点包括&#xff1a; 直接性&#xff1a;与操作系统深度绑定&#xff0c;直接使用系统库和内核功能 。定制化&#xff1a;支持通过…

Rust 2025:内存安全革命与异步编程新纪元

Rust 2025 Edition通过区域内存管理、泛型关联类型和零成本异步框架三大革新&#xff0c;重新定义系统级编程语言的能力边界。本次升级不仅将内存安全验证效率提升80%&#xff0c;更通过异步执行器架构优化实现微秒级任务切换。本文从编译器原理、运行时机制、编程范式转型三个…

std::unorderd_map 简介

1. unorderd_map 简介 1. unorderd_map 简介 简介1.1. 实现原理1.2. 函数1.3. 问题集 1.3.1. emplace、emplace_hint、insert 的区别 1.4. 参考链接 简介 unordered_map 是 C 标准库中的一个容器&#xff0c;它定义在 <unordered_map> 头文件里。它借助哈希表来存储键…

在线测试来料公差

UI 上图 V1 上图 V2 V3 Code import tkinter as tk from tkinter import messagebox, scrolledtext import socket import threading from datetime import datetime import os import logging from PIL import Image, ImageTk import subprocess# 定义文件夹路径…

【优秀三方库研读】【C++基础知识】odygrd/quill -- 折叠表达式

compute_encoded_size_and_cache_string_lengths 方法中这段代码是一个C的折叠表达式&#xff08;fold expression&#xff09;的应用&#xff0c;用于计算多个参数编码后的总大小。下面我将详细解释这段代码的每个部分&#xff0c;并说明为什么这样写。 代码如下&#xff1a; …

数据库安装和升级和双主配置

备份和导入数据 ./mysqldump -u root -p123321 test > test.sql rsync -av test.sql root192.168.0.212:/usr/local/mysql/ ./mysql -uroot -p test < …/test.sql sudo tar -zxvf mysql-5.7.44-linux-glibc2.12-x86_64.tar.gz -C /usr/local/ sudo ln -sfn /usr/loca…

【C语言】条件编译

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:C语言 ⚙️操作环境:Visual Studio 2022 目录 条件编译 常用的预处理指令 核心应用场景 1.防止头文件重复包含 2.跨平台兼容性 3.调试模式与发布模式 4.功能开关 5.代码兼容性处理 结语 条件编译 一般情况下,源程序中所有…

如何在安卓平板上下载安装Google Chrome【轻松安装】

安卓平板可以通过系统内置的应用商店直接搜索并下载谷歌浏览器。用户打开平板上的“Play 商店”&#xff0c;在搜索框输入Google Chrome。出现结果后&#xff0c;点击第一个带有“Google LLC”字样的应用图标&#xff0c;然后点“安装”按钮。下载和安装时间和网速有关&#xf…

.NET代码保护混淆和软件许可系统——Eziriz .NET Reactor 7

.NET代码保护混淆和软件许可系统——Eziriz .NET Reactor 7 1、简介2、功能特点3、知识产权保护功能4、强大的许可系统5、软件开发工具包6、部署方式7、下载 1、简介 .NET Reactor是用于为.NET Framework编写的软件的功能强大的代码保护和软件许可系统&#xff0c;并且支持生成…

利用 SSE 实现文字吐字效果:技术与实践

利用 SSE 实现文字吐字效果:技术与实践 引言 在现代 Web 应用开发中,实时交互功能愈发重要。例如,在线聊天、实时数据监控、游戏中的实时更新等场景,都需要服务器能够及时将数据推送给客户端。传统的请求 - 响应模式在处理实时性要求较高的场景时显得力不从心,而 Server…