每天一个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()
相关文章:
每天一个Flutter开发小项目 (4) : 构建收藏地点应用 - 深入Flutter状态管理
引言 欢迎回到 每天一个Flutter开发小项目 系列博客!在前三篇博客中,我们从零开始构建了计数器应用、待办事项列表应用,以及简易天气应用。您不仅掌握了 Flutter 的基础组件和布局,还学习了网络请求、JSON 解析等实用技能,更重要的是,我们一起探讨了高效的 Flutter 学习…...
qt-C++笔记之QtCreator新建项目即Create Project所提供模板的逐个尝试
qt-C笔记之QtCreator新建项目即Create Project所提供模板的逐个尝试 code review! 文章目录 qt-C笔记之QtCreator新建项目即Create Project所提供模板的逐个尝试1.Application(Qt):Qt Widgets Application1.1.qmake版本1.2.cmake版本 2.Application(Qt):Qt Console Applicati…...
【NestJS系列】安装官方nestjs CLI 工具
环境搭建指南:从零开始创建 NestJS 项目 一、工具准备 1. 安装 Node.js 环境 推荐使用 LTS 版本(目前 20.x 以上)验证安装:终端执行 node -v 和 npm -vNode.js 官网下载2. 包管理器选择 这里选用更高效的 pnpm,你也可选择 npm 或 yarn # 安装 pnpm npm install -g pnp…...
【Springboot知识】Logback从1.2.x升级到1.3.x需要注意哪些点?
文章目录 **1. 确认依赖版本**示例依赖配置(Maven): **2. 处理 StaticLoggerBinder 的移除**解决方案: **3. 修改日志配置文件**示例 logback.xml 配置: **4. 检查兼容性问题**Spring Boot 2.x 的兼容性解决方案&#…...
【Linux C | 时间】localtime 的介绍、死机、死锁问题以及 localtime_r 函数的时区问题
😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C、数据结构、音视频🍭 🤣本文内容🤣&a…...
每日一题——LRU缓存机制的C语言实现详解
LRU缓存机制的C语言实现详解 参考1. 数据结构设计双向链表节点哈希表节点哈希表LRU缓存结构 2. 初始化哈希表和双向链表哈希函数初始化哈希表初始化双向链表创建LRU缓存 3. 更新双向链表4. 实现Get操作5. 实现Put操作更新节点值删除最久未使用节点插入或更新节点 6. 释放缓存释…...
虚函数表和虚函数表指针
1.虚函数表什么时候生成? 编译器编译的时候生成 2.虚函数表存放在哪里? 讨论两种情况:在磁盘(可执行程序)、在内存(运行状态) 3.虚函数表与虚函数表指针的关系 每个类只有一个虚函数&#x…...
计算机毕业设计SpringBoot+Vue.js图书进销存管理系统(源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
3-2 WPS JS宏 工作簿的打开与保存(模板批量另存为工作)学习笔记
************************************************************************************************************** 点击进入 -我要自学网-国内领先的专业视频教程学习网站 *******************************************************************************************…...
大白话Vuex 核心概念(state、mutations、actions)的使用案例与原理
大白话Vuex 核心概念(state、mutations、actions)的使用案例与原理 Vuex是Vue.js应用程序中专门用来管理状态的工具,就好像是一个大管家,帮你把项目里一些重要的数据和操作管理得井井有条。下面用大白话结合案例来介绍Vuex核心概…...
【学写LibreCAD】1 LibreCAD主程序
一、源码 头文件: #ifndef MAIN_H #define MAIN_H#include<QStringList>#define STR(x) #x #define XSTR(x) STR(x)/*** brief handleArgs* param argc cli argument counter from main()* param argv cli arguments from main()* param argClean a list…...
CentOS7最小化安装中使用curl安装yum和wget
在 CentOS 7 最小化安装中,如果已经有curl工具,可以按照以下步骤使用它来安装yum和wget: 1. 备份原有的 yum 源配置文件 为了避免配置冲突或后续需要恢复,先备份原有的yum源配置文件。 mv /etc/yum.repos.d/CentOS-Base.repo /…...
【Linux】learning notes(3)make、copy、move、remove
文章目录 1、mkdir (make directory)2、rmdir (remove directory)3、rm(remove)4、>5、touch 新建文件6、mv(move)7、cp(copy) 1、mkdir (make…...
P10108 [GESP202312 六级] 闯关游戏
题目大意 如题 分析 设最佳通关方案为 { s 1 , s 2 , . . . , s k } \{s_1,s_2,...,s_k\} {s1,s2,...,sk},其中 s i s_i si 代表第 i i i 次到达的关卡( ≥ N \ge N ≥N 的不算)。 当 a k N − 1 a_kN-1 akN−1 时&#…...
Dubbo RPC 原理
一、Dubbo 简介 Apache Dubbo 是一款高性能、轻量级的开源 RPC 框架,支持服务治理、协议扩展、负载均衡、容错机制等核心功能,广泛应用于微服务架构。其核心目标是解决分布式服务之间的高效通信与服务治理问题。 二、Dubbo 架构设计 1. 核心组件 Prov…...
网络安全 机器学习算法 计算机网络安全机制
(一)网络操作系统 安全 网络操作系统安全是整个网络系统安全的基础。操作系统安全机制主要包括访问控制和隔离控制。 访问控制系统一般包括主体、客体和安全访问政策 访问控制类型: 自主访问控制强制访问控制 访问控制措施: 入…...
【Jenkins】一种灵活定义多个执行label节点的jenkinsfile写法
确定执行机器和自定义工作目录(忽略节点的workspace) pipeline{agent {node {label "XXXXX"customWorkspace "E:/workspace/"}}parameters {}options {}stages {}post {} }仅确定执行机器 pipeline{agent { label "XXXXX&quo…...
Web自动化之Selenium控制已经打开的浏览器(Chrome,Edge)
在使用selenium进行web自动化或爬虫的时候,经常会面临登录的情况,对于这种情况,我们可以利用Selenium控制已经打开的浏览器,从而避免每次都需要重新打开浏览器并进行登录的繁琐步骤。 目录 说明 启动浏览器 注意 --user-data-dir说明 代码设定 代码 改进代…...
【万字长文】开源之播对话白鲸开源CEO郭炜--乐观主义的开源精神走得更远
本文为白鲸开源科技CEO郭炜1小时深度访谈全记录 来源于:开源之播」Episode15:对话郭炜–乐观主义的开源精神走得更远 大家好,我是郭炜,开源圈的“郭大侠”。作为 Apache 基金会的成员,我曾参与并孵化了多个开源项目,如…...
Verilog 位运算符和逻辑运算符的使用
Verilog 位运算符和逻辑运算符的使用 目录 前言 一、逻辑运算符 二、位运算符 总结 前言 本文详细描述了Verilog 逻辑运算符和位运算符的使用,随着编程的熟练,有时候总是喜欢混用它们,虽然能实现同样的功能,但最好还是注意一下…...
压测报告:DeepSeek-R1-Distill-Qwen-32B模型性能评估
1. 实验背景 本实验旨在评估DeepSeek-R1-Distill-Qwen-32B模型在特定硬件配置下的性能表现。测试硬件为GPU服务器。实验主要关注模型在不同并发请求数下的峰值生成速度。 吞吐量(Throughput): 测试模型在单位时间内可以处理多少请求,通常以“每秒生成的令牌数(tokens/s)…...
【论文笔记】ClipSAM: CLIP and SAM collaboration for zero-shot anomaly segmentation
原文链接 摘要 近年来,CLIP 和 SAM 等基础模型在零样本异常分割 (ZSAS) 任务中展现出良好的性能。然而,无论是基于 CLIP 还是基于 SAM 的 ZSAS 方法,仍然存在不可忽视的关键缺陷:1) CLIP 主要关注不同输入之间的全局特征对齐&am…...
DeepSeek:面向效率与垂直领域的下一代大语言模型技术解析
本文将深入剖析DeepSeek模型的核心算法架构,揭示其在神经网络技术上的突破性创新,并与主流大模型进行全方位技术对比。文章涵盖模型设计理念、训练范式优化、应用场景差异等关键维度,为读者呈现大语言模型领域的最新发展图景。 一、DeepSeek…...
win32汇编环境,加速键的应用示例
;运行效果 ;win32汇编环境,加速键的应用示例 ;加速键,就是按某个键,开启某个功能。不用鼠标点来点去的东西。 ;直接抄进RadAsm可编译运行。重要部分加备注。 ;下面为asm文件 ;>>>>>>>>>>>>>>>>>>…...
【计算机网络】OSI模型、TCP/IP模型、路由器、集线器、交换机
一、计算机网络分层结构 计算机网络分层结构 指将计算机网络的功能划分为多个层次,每个层次都有其特定的功能和协议,并且层次之间通过接口进行通信。 分层设计的优势: 模块化:各层独立发展(如IPv4→IPv6,…...
[Web 安全] 反序列化漏洞 - 学习笔记
关注这个专栏的其他相关笔记:[Web 安全] Web 安全攻防 - 学习手册-CSDN博客 0x01:反序列化漏洞 — 漏洞介绍 反序列化漏洞是一种常见的安全漏洞,主要出现在应用程序将 序列化数据 重新转换为对象(即反序列化)的过程中…...
每日一题——字母异位词分组
字母异位词分组 1. 问题描述示例提示 2. 解题思路具体步骤 3. 代码实现4. 代码解析(1)排序法(2)哈希表存储(3)动态内存分配(4)释放内存1. HASH_FIND_STR 的作用2. 宏的定义4. 详细解…...
力扣 807. 保持城市天际线(Java实现)
题目分析 给定一个二维数组,行列长度相等,要保持四个方向仍一观察高度不变的情况下,适当添加建筑高度,问最大高度增量和。所谓四个方向高度不变的增量,其实就是arr[i][j]与同i行最大值同j列最大值之间的最小值的差&…...
【视频2 - 4】初识操作系统,Linux,虚拟机
📝前言说明: ●本专栏主要记录本人的基础算法学习以及LeetCode刷题记录,主要跟随B站博主灵茶山的视频进行学习,专栏中的每一篇文章对应B站博主灵茶山的一个视频 ●题目主要为B站视频内涉及的题目以及B站视频中提到的“课后作业”。…...
重启securecmd失败
重启securecmd失败 问题描述:KES集群部署工具中,节点管理里新增节点下一步报错无法检查securecmd端口进程情况,安装依赖包后再次下一步提示如下报错: 解决办法: [rootlocalhost cluster]# cd /home/kingbase/cluster…...
python学习四
python运算符与表达式 表达式: Python中的表达式是一种计算结果的代码片段。它可以包 含变量、运算符、常数和函数调用,用于执行各种数学、逻辑 和功能操作 算术运算符: 比较(关系)运算符: 赋值运算符: 逻辑运算符: 位运算符: 成员运算符: 身份运算符 <...
LeetCode 236.二叉树的最近公共祖先
题目: 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节…...
react 中,使用antd layout布局中的sider 做sider的展开和收起功能
一 话不多说,先展示效果: 展开时: 收起时: 二、实现代码如下 react 文件 import React, {useState} from react; import {Layout} from antd; import styles from "./index.module.less"; // 这个是样式文件&#…...
2025-02-26 学习记录--C/C++-C语言 整数格式说明符
合抱之木,生于毫末;九层之台,起于累土;千里之行,始于足下。💪🏻 C语言 整数格式说明符 【例如 】🎀 :在 C 语言中,%ld 是 printf 或 scanf 等格式化输入输出函…...
绕过过滤order by
一、常见绕过技术 1、注释符截断 利用注释符(如 --、#)截断后续查询,消除过滤逻辑的影响。 ORDER BY 1-- 若原查询为 SELECT * FROM table ORDER BY 用户输入,注入后可能忽略后续过滤逻辑。 2、大小写混淆/编码绕过 若过滤是大…...
NLP09-加强1-对比SVM
支持向量机(SVM) (一)导入 SVM 相关库 (二) 修改模型初始化 (三) 比较 朴素贝叶斯分类器 SVM分类器 支持向量机(SVM) 代码修改基于NLP09-朴素贝叶斯问句…...
STM32——HAL库开发笔记22(定时器3—呼吸灯实验)(参考来源:b站铁头山羊)
本文利用前几节所学知识来实现一个呼吸灯实验:两颗led灯交替呼吸。 一、STM32CubeMX配置 step1:配置调试接口 step2:配置定时器 定时器1位于APB2总线上,如上图所示。 step3:配置时基单元 按照下图配置 时钟来源配置…...
Vue3+TypeScript 封装一个好用的防抖节流自定义指令
一、前言:为什么需要防抖节流? 在前端开发中,高频触发的事件(如滚动、输入、点击等)容易导致性能问题。防抖(debounce) 和 节流(throttle) 是两种常用的优化手段&#x…...
2025年中国最新安防行业数字安全现状与未来趋势:内生安全成核心共识,从零基础到精通,收藏这篇就够了!
本次,我将为大家剖析由**安奇信发布的《中国安防行业数字安全建设与发展情况白皮书**》。该报告共_37_页,涵盖了众多重要信息和核心论点。若您希望深入了解,请参阅原报告,获取方法已在文档的最后部分提供。 报告核心内容 随着数字…...
项目管理的新理念主要有哪些
随着时代的发展和市场需求的变化,项目管理的理念也在不断地创新和演变。项目管理的新理念包括敏捷管理、精益管理、知识管理、变革管理、协作式管理和项目生命周期管理等。这些新理念不仅能够提高项目的管理效率,还能帮助团队在复杂的环境中更好地应对挑…...
Spring如何解决循环依赖?
一、Spring的三级缓存 关键就是提前暴露未完全创建完毕的Bean。 三级缓存来解决循环依赖: 一级缓存:用于存储完全初始化完成的单例Bean。 二级缓存:用于存储尚未完全初始化,但已实例化的Bean,用于提前暴露对象&#x…...
vscode java环境中文乱码的问题
先说我的结论: 由于我的系统是windows的,所以vscode使用的是默认gbk的编码进行的。 但是我的目的是全部都使用utf-8,因为我的程序始终是要去linux上去运行的,总不能在本地是好的,然后到服务器上就不行了吧,…...
十、大数据资源平台功能架构
一、大数据资源平台的功能架构图总体结构 大数据资源平台功能架构图 关键组件: 1.用户(顶行) 此部分标识与平台交互的各种利益相关者。 其中包括: 市领导 各部门分析师 区政府 外部组织 公民 开发人员 运营经理 2.功能模…...
OpenEuler学习笔记(三十五):搭建代码托管服务器
以下是主流的代码托管软件分类及推荐,涵盖自托管和云端方案,您可根据团队规模、功能需求及资源情况选择: 一、自托管代码托管平台(可私有部署) 1. GitLab 简介: 功能全面的 DevOps 平台,支持代码托管、C…...
使用Spring AI调用Ollama的DeepSeek模型实现结构化输出
在 Docker 环境中部署 Ollama 并使用 Spring AI 框架实现结构化输出,你可以按照以下步骤进行操作: 1. 部署 Ollama 模型 首先,需要在 Docker 中部署 Ollama 并下载 deepseek-r1:1.5b 模型。 1.1 准备部署文件 version: 3.8services:ollam…...
微信小程序调用火山方舟(字节跳动火山引擎)中的DeepSeek大模型
微信小程序的轻量化特性与DeepSeek大模型的AI能力结合,可快速构建智能问答、内容生成等场景化服务。通过火山方舟平台提供的标准化接口,开发者无需深入算法细节即可调用模型能力。 一、注册火山引擎账号,创建API Key和model(接入…...
threejs:射线拾取封装
射线拾取封装代码: import * as THREE from three; // 点击事件// 1.坐标转化(鼠标单击的屏幕坐标转标准设备坐标)// 2.射线计算(通过鼠标单击位置相机参数计算射线值)// 3.射线交叉计算// ObjectsArr是用来做射线拾取的对象数组,一个二维数组 export f…...
2024年国赛高教杯数学建模D题反潜航空深弹命中概率问题解题全过程文档及程序
2024年国赛高教杯数学建模 D题 反潜航空深弹命中概率问题 原题再现 应用深水炸弹(简称深弹)反潜,曾是二战时期反潜的重要手段,而随着现代军事技术的发展,鱼雷已成为现代反潜作战的主要武器。但是,在海峡或…...
爬虫框架与库
爬虫框架与库是用于网络数据抓取的核心工具,帮助开发者高效地从网页中提取结构化数据。 Requests:用于发送HTTP请求。 BeautifulSoup:用于解析HTML和XML。 Scrapy:强大的爬虫框架,适合大规模爬取。 Selenium&#…...
从电子管到量子计算:计算机技术的未来趋势
计算机发展的历史 自古以来人类就在不断地发明和改进计算工具,从结绳计数到算盘,计算尺,手摇计算机,直到1946年第一台电子计算机诞生,虽然电子计算机至今虽然只有短短的半个多世纪,但取得了惊人的发展吗,已经经历了五代的变革。计算机的发展和电子技术的发展密切相关,…...