每天一個Flutter開發小項目 (4) : 構建收藏地點應用 - 深入Flutter狀態管理

引言

歡迎回到 每天一個Flutter開發小項目 系列博客!在前三篇博客中,我們從零開始構建了計數器應用、待辦事項列表應用,以及簡易天氣應用。您不僅掌握了 Flutter 的基礎組件和布局,還學習了網絡請求、JSON 解析等實用技能,更重要的是,我們一起探討了高效的 Flutter 學習方法。

隨著應用功能的日益豐富和復雜,簡單的 setState 狀態管理方式逐漸顯得力不從心。當應用狀態需要在多個 Widget 之間共享和傳遞時,或者當狀態邏輯變得復雜時,我們需要更專業、更高效的狀態管理方案。

今天,我們將深入 Flutter 的核心概念之一——狀態管理,并借助強大的 Provider 狀態管理庫,構建一個實用的 收藏地點應用。 通過這個項目,您將學習到:

  • Flutter 狀態管理的核心概念: 深入理解 Widget 樹、狀態提升、狀態共享等概念。
  • Provider 狀態管理庫的使用: 掌握 Provider 的核心組件和用法,如 ChangeNotifierProvider, Consumer, Provider.of 等。
  • 更合理的應用架構: 學習如何使用 Provider 組織和管理應用狀態,構建更清晰、更易維護的應用架構。
  • 狀態管理最佳實踐: 了解在實際項目中如何選擇和應用合適的狀態管理方案。
  • 技能躍遷: 從簡單的 setState 進階到專業的 Provider 狀態管理,提升您的 Flutter 開發能力。

項目簡介: 收藏地點應用

我們的收藏地點應用將圍繞以下核心功能展開:

  • 添加地點: 用戶可以輸入地點名稱和描述,將喜愛的地點添加到收藏列表。
  • 查看地點列表: 清晰地展示所有收藏的地點,包括地點名稱和描述。
  • 收藏/取消收藏: 用戶可以標記地點為 “已收藏” 或 “未收藏” 狀態。
  • 數據持久化 (可選): 將收藏地點數據持久化存儲 (本篇博客暫不涉及數據持久化,后續博客會講解)。

通過構建收藏地點應用,我們將深入實踐:

  • Provider 狀態管理: 使用 Provider 管理地點列表和收藏狀態。
  • 復雜 UI 構建: 構建包含列表展示、用戶輸入、狀態切換等交互的 UI 界面。
  • 應用架構設計: 初步體驗如何使用 Provider 組織和設計 Flutter 應用架構。

Flutter 狀態管理核心概念回顧

在深入 Provider 之前,我們先簡要回顧 Flutter 狀態管理的核心概念。

  • Widget 是不可變的: 在 Flutter 中,Widget 是不可變的 (immutable)。 一旦 Widget 被創建,其屬性就不能被修改。 如果 Widget 的狀態需要改變,我們需要重新構建 Widget。
  • State 是可變的: State (狀態) 與 Widget 關聯,用于存儲 Widget 的可變數據。 State 對象可以在其生命周期內被修改,當 State 對象發生改變時,會觸發 Widget 的重新構建。
  • setState() 觸發狀態更新: setState() 方法是 Flutter 中最基礎的狀態管理方式。 調用 setState() 會通知 Flutter 框架,State 對象中的數據已經發生改變,需要重新構建 Widget。
  • Widget 樹和狀態傳遞: Flutter 應用由 Widget 樹構成。 狀態可以在 Widget 樹中傳遞。 父 Widget 可以將狀態傳遞給子 Widget,子 Widget 可以通過回調函數通知父 Widget 狀態發生改變。
  • 狀態提升 (Lifting State Up): 當多個 Widget 需要訪問和修改同一個狀態時,可以將該狀態提升到它們共同的父 Widget 中管理,實現狀態共享。

為什么需要更專業的狀態管理方案?

雖然 setState() 可以滿足簡單的狀態管理需求,但當應用變得復雜時,setState() 會面臨以下挑戰:

  • 代碼難以維護: 當狀態分散在各個 Widget 中,且 Widget 之間狀態依賴關系復雜時,代碼會變得難以理解和維護。
  • 狀態傳遞繁瑣: 在深層 Widget 樹中傳遞狀態,需要逐層傳遞,代碼冗余且容易出錯。
  • 性能問題: 過度使用 setState() 可能導致不必要的 Widget 重新構建,影響應用性能。

更專業的狀態管理方案 (如 Provider, BLoC, Riverpod 等) 旨在解決上述問題,提供更高效、更易維護、更可擴展的狀態管理機制。

Provider 狀態管理庫簡介

Provider 是一個由 Flutter 社區維護的流行的狀態管理庫。它基于 依賴注入 (Dependency Injection) 的設計模式,以簡潔、易用的方式管理應用狀態。

Provider 的核心思想是將 狀態 (數據) 暴露給 Widget 樹, 使得任何 Widget 都可以方便地訪問和監聽狀態變化。

Provider 的主要優點包括:

  • 簡單易用: API 簡潔直觀,易于學習和上手。
  • 代碼清晰: 將狀態管理邏輯從 Widget 中分離出來,使代碼結構更清晰、更易維護。
  • 高效更新: Provider 只會精確更新需要更新的 Widget,避免不必要的 Widget 重新構建,提升性能。
  • 強大的擴展性: Provider 支持多種狀態管理模式,可以靈活應對各種復雜的應用場景。
  • 官方推薦: Provider 是 Flutter 官方推薦的狀態管理方案之一。

實戰步驟: 構建收藏地點應用

接下來,我們將一步步使用 Provider 構建我們的收藏地點應用。

步驟 1: 創建新的 Flutter 項目并添加 Provider 依賴

首先,創建一個新的 Flutter 項目,命名為 favorite_places_app

然后在 pubspec.yaml 文件中添加 provider 依賴:

dependencies:flutter:sdk: flutterprovider: ^6.0.0 # 使用最新版本,請查閱 pub.dev 獲取最新版本號

運行 flutter pub get 命令獲取依賴。

步驟 2: 定義數據模型 (Place)

我們需要定義一個 Place 類來表示地點數據,包含地點名稱和描述。

創建 lib/models/place.dart 文件,定義 Place 類:

class Place {final String name;final String description;bool isFavorite;Place({required this.name,required this.description,this.isFavorite = false,});//  切換收藏狀態的方法void toggleFavoriteStatus() {isFavorite = !isFavorite;}
}

代碼解釋:

  • Place: 定義了 Place 類,包含 name (地點名稱), description (地點描述), isFavorite (是否收藏) 三個屬性。
  • isFavorite 屬性: bool 類型,默認為 false,表示初始狀態為未收藏。
  • toggleFavoriteStatus() 方法: 用于切換地點的收藏狀態,將 isFavorite 屬性取反。

步驟 3: 創建狀態管理類 (PlacesProvider)

我們需要創建一個狀態管理類 PlacesProvider 來管理地點列表和相關的狀態邏輯。 PlacesProvider 類需要繼承自 ChangeNotifier,以便 Provider 可以監聽狀態變化并通知 Widget 重新構建。

創建 lib/providers/places_provider.dart 文件,定義 PlacesProvider 類:

import 'package:flutter/material.dart';
import '../models/place.dart';class PlacesProvider extends ChangeNotifier {final List<Place> _places = []; //  私有地點列表List<Place> get places => [..._places]; //  提供地點列表的 getter 方法void addPlace(Place place) { //  添加地點的方法_places.add(place);notifyListeners(); //  通知監聽器狀態已改變}void toggleFavorite(Place place) { //  切換地點收藏狀態的方法final placeIndex = _places.indexOf(place);_places[placeIndex].toggleFavoriteStatus()

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/70858.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/70858.shtml
英文地址,請注明出處:http://en.pswp.cn/web/70858.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Visual Studio打開文件后,中文變亂碼的解決方案

文件加載 使用Unicode&#xff08;UTF-8&#xff09;編碼加載文件 C:\WorkSpace\Assets\Scripts\UI\View\ExecuteComplateView.cs時&#xff0c;有些字節已用Unicode替換字符替換。保存該文件將不會保留原始文件內容。

OpenGL ES -> GLSurfaceView繪制點、線、三角形、正方形、圓(頂點法繪制)

XML文件 <?xml version"1.0" encoding"utf-8"?> <com.example.myapplication.MyGLSurfaceViewxmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"…

threejs 安裝教程

嗨&#xff0c;我是小路。今天主要和大家分享的主題是“threejs 安裝教程”。 在當今的數字化時代&#xff0c;用戶對視覺體驗的要求越來越高。傳統的2D網頁已經無法滿足所有需求&#xff0c;而三維&#xff08;3D&#xff09;圖形技術則為前端開發者提供了新的方向。…

win11編譯pytorch cuda128版本流程

Geforce 50xx系顯卡最低支持cuda128&#xff0c;torch cu128 release版本目前還沒有釋放&#xff0c;所以自己基于2.6.0源碼自己編譯wheel包。 1. 前置條件 1. 使用visual studio installer 安裝visual studio 2022&#xff0c;工作負荷選擇【使用c的桌面開發】,安裝完成后將…

如何安裝Vm和centos

一、VMware 安裝 &#xff08;一&#xff09;前期準備 下載 VMware 軟件&#xff1a;首先&#xff0c;你需要從 VMware 官方網站下載適合你計算機操作系統版本的 VMware Workstation 軟件安裝包。確保選擇的版本與你的主機操作系統兼容&#xff0c;例如&#xff0c;如果你的主…

OpenGL 04--GLSL、數據類型、Uniform、著色器類

一、著色器 在 OpenGL 中&#xff0c;著色器&#xff08;Shader&#xff09;是運行在 GPU 上的程序&#xff0c;用于處理圖形渲染管線中的不同階段。 這些小程序為圖形渲染管線的某個特定部分而運行。從基本意義上來說&#xff0c;著色器只是一種把輸入轉化為輸出的程序。著色器…

服務器離線部署DeepSeek

目標 本次部署的目標是在本地服務器上部署DeepSeek。但是該服務不能連接外網&#xff0c;因此只能使用離線部署的方式。為了一次完成部署。現在云服務器上進行嘗試。 云服務器部署嘗試 云服務器配置 CentOS72080Ti 11GB 安裝準備 1、上傳iso并配置為本地yum源 安裝前先將…

刪除idea recent projects 記錄

1、退出idea&#xff08;一定要全部退出idea&#xff0c;要不然刪除后&#xff0c;idea一退出&#xff0c;又保存上了&#xff09; 2、進入 C:\Users\Administrator\AppData\Roaming\JetBrains\IntelliJIdea2024.1\options 目錄 根據不同的版本號 IntelliJIdea2024.1 這個地方…

【MySql】EXPLAIN執行計劃全解析:15個字段深度解讀與調優指南

文章目錄 一、執行計劃核心字段總覽二、關鍵字段深度拆解1. type&#xff08;訪問類型&#xff09;——查詢性能的晴雨表典型場景分析&#xff1a; 2. key_len&#xff08;索引使用長度&#xff09;——索引利用率的檢測儀計算示例&#xff1a; 3. Extra&#xff08;附加信息&a…

如何實現一個 Spring Boot Starter

在 Spring Boot 中&#xff0c;Starter 是一種自動配置的模塊&#xff0c;它封裝了一些常用的功能&#xff0c;并通過 Spring Boot 的約定大于配置的原則&#xff0c;使開發者能夠快速使用和集成相關功能。通常&#xff0c;Spring Boot Starter 包含了所需的依賴、配置、自動化…

使用python做http代理請求

有這樣一個需求現在有兩臺A&#xff0c;B兩臺電腦組成了一個局域網&#xff0c;在A電腦上開發webjava應用&#xff0c;需要調用第三方接口做http請求&#xff0c;但是這個請求只能在B電腦上請求。 一種解決方案&#xff1a;自定義一個中間服務&#xff0c;在電腦B上運行一個簡…

系統架構設計師考點——嵌入式技術

一、備考指南 嵌入式技術主要考查的是嵌入式基礎知識、嵌入式設計等相關知識&#xff0c;在系統架構設計師的考試中選擇題占2~4分&#xff0c;案例分析有時會考關鍵路徑的技術問答&#xff0c;這個題目一般比較難&#xff0c;但是由于案例分析題是五題選三題&#xff0c;所以…

當AI重構認知:技術狂潮下的教育沉思錄

備注&#xff1a;文章未Deepseek R1模型輔助生成&#xff0c;如有不妥請諒解。 以下使原文&#xff1a; 我有三個娃&#xff0c;各間隔4到5歲&#xff0c;經歷過搜索引擎&#xff0c;短視頻&#xff0c;短劇&#xff0c;本身曾經也是教育專業出生&#xff0c;任何事務都有兩面性…

EasyExcel 實踐案例:打印工資條

文章目錄 &#x1f4a1; 1. 每個員工一個 Excel 文件? 占位符格式&#x1f4cc; Excel 模板&#x1f4cc; Java 代碼&#x1f525; 關鍵點 &#x1f4a1; 2. 每個員工一個 Sheet? 占位符格式&#x1f4cc; Java 代碼&#x1f525; 關鍵點 &#x1f4a1; 3. 一個 Sheet&#x…

編程題-從前序與中序遍歷序列構造二叉樹(中等-重點)

題目&#xff1a; 給定兩個整數數組 preorder 和 inorder &#xff0c;其中 preorder 是二叉樹的先序遍歷&#xff0c; inorder 是同一棵樹的中序遍歷&#xff0c;請構造二叉樹并返回其根節點。 提示: preorder 和 inorder 均 無重復 元素 解法一&#xff08;遞歸&#xff0…

Vue 3 + Vite 項目配置訪問地址到服務器某個文件夾的解決方案

前言 在開發 Vue 3 Vite 項目時&#xff0c;我們經常需要將項目部署到服務器的某個特定文件夾下。例如&#xff0c;將項目部署到 /my-folder/ 目錄下&#xff0c;而不是服務器的根目錄。這時&#xff0c;我們需要對 Vite 和 Vue Router 進行一些配置&#xff0c;以確保項目能…

【Rust中級教程】2.10. API設計原則之受約束性(constrained) Pt.1:對類型進行修改、`#[non_exhaustive]`注解

喜歡的話別忘了點贊、收藏加關注哦&#xff08;加關注即可閱讀全文&#xff09;&#xff0c;對接下來的教程有興趣的可以關注專欄。謝謝喵&#xff01;(&#xff65;ω&#xff65;) 2.10.1. 接口的更改要三思 如果你的接口要做出對用戶可見的更改&#xff0c;那么一定要三思…

Imagination GPU 3D Graphics Wrokload

本次分享Imagination GPU 的3D 圖像處理負載流程。 總的分為兩個階段 第一階段&#xff1a;Geometry Processing Phase&#xff08;幾何處理階段&#xff09;是渲染管線中的一個關鍵環節&#xff0c;主要負責對三維幾何數據進行處理和變換&#xff0c;以便后續在屏幕上進行顯…

自動化設備對接MES系統找DeepSeek問方案

項目需要現場的PLC設備HTTP協議JSON格式的方式對接MES系統平臺&#xff0c;于是試了一下&#xff1a; 找到的相關資源鏈接在這里。

VoIP之音頻3A技術

音頻3A技術是改善語音通話質量的三種關鍵技術的簡稱&#xff0c;包括聲學回聲消除&#xff08;Acoustic Echo Cancellation, AEC&#xff09;、自動增益控制&#xff08;Automatic Gain Control, AGC&#xff09;、自噪聲抑制&#xff08;Automatic Noise Suppression, ANS&…