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.pswp.cn/diannao/80322.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/80322.shtml
英文地址,請注明出處:http://en.pswp.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…