每天一个Flutter开发小项目 (4) : 构建收藏地点应用 - 深入Flutter状态管理

news/2025/2/26 12:57:50

引言

欢迎回到 每天一个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: flutter
  provider: ^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.niftyadmin.cn/n/5868730.html

相关文章

Redis面试知识点总结

目录 1. Redis 基础知识2. 基本数据结构&#xff08;底层实现&#xff09;2.1 SDS2.2 链表2.3 字典2.4 跳跃表2.5 整数集合2.6 压缩列表 3. 对象3.1 字符串对象3.2 列表对象3.3 哈希对象3.4 集合对象 set3.5 有序集合对象 zset 4. 数据库4.1 RDB 持久化4.2 AOF 持久化4.3 数据淘…

力扣2454. 下一个更大元素 IV

力扣2454. 下一个更大元素 IV 题目 题目解析及思路 题目要求对于每个数&#xff0c;找到右边比它大的第二个数&#xff0c;并记录在ans数组中 如果是右边第一个大的&#xff0c;就用一个递减栈即可&#xff0c;栈顶元素如果<当前元素则弹出 第二个大数就要利用弹出的栈顶…

AI大模型(四)基于Deepseek本地部署实现模型定制与调教

AI大模型&#xff08;四&#xff09;基于Deepseek本地部署实现模型定制与调教 DeepSeek开源大模型在榜单上以黑马之姿横扫多项评测&#xff0c;其社区热度指数暴涨、一跃成为近期内影响力最高的话题&#xff0c;这个来自中国团队的模型向世界证明&#xff1a;让每个普通人都能…

leetcode_动态规划/递归 70. 爬楼梯

70. 爬楼梯 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 思路&#xff1a; 考虑: 假设现在已经爬到了某一阶台阶&#xff0c;那是如何到达这里的呢&#xff1f;可能是从前一阶台阶爬上来的&am…

服务器硬件老化导致性能下降的排查与优化

当服务器硬件老化导致性能下降时&#xff0c;以下是一些排查和优化方法&#xff1a; ### 排查问题&#xff1a; 1. **性能监控&#xff1a;** - 使用监控工具&#xff08;如Prometheus、Grafana&#xff09;监视服务器性能指标&#xff0c;包括CPU利用率、内存使用、磁盘I…

使用python接入腾讯云DeepSeek

本文主要从提供SSE方式接入DeepSeek&#xff0c;并通过fastapi websocket对外提供接入方法。 参考文档&#xff1a; 腾讯云大模型&#xff1a;https://cloud.tencent.com/document/product/1759/109380 fastAPI官网&#xff1a;https://fastapi.tiangolo.com/ WebSocketManager…

Python从0到100(八十九):Resnet、LSTM、Shufflenet、CNN四种网络分析及对比

前言&#xff1a; 零基础学Python&#xff1a;Python从0到100最新最全教程。 想做这件事情很久了&#xff0c;这次我更新了自己所写过的所有博客&#xff0c;汇集成了Python从0到100&#xff0c;共一百节课&#xff0c;帮助大家一个月时间里从零基础到学习Python基础语法、Pyth…

STM32MP157A-FSMP1A单片机移植Linux系统SPI总线驱动

SPI总线驱动整体上与I2C总线驱动类型&#xff0c;差别主要在设备树和数据传输上&#xff0c;由于SPI是由4根线实现主从机的通信&#xff0c;在设备树上配置时需要对SPI进行设置。 原理图可知&#xff0c;数码管使用的SPI4对应了单片机上的PE11-->SPI4-NSS,PE12-->SPI4-S…