Flutter笔记:滚动之-无限滚动与动态加载的实现(GetX简单状态管理版)

Flutter笔记
无限滚动与动态加载的实现
(GeX简单状态管理版)

作者李俊才 (jcLee95):https://blog.csdn.net/qq_28550263
邮箱 :291148484@163.com
本文地址:https://blog.csdn.net/qq_28550263/article/details/133365040

GetX简单状态管理提供了一种更高效的且用于取代Flutter有状态组件(StatefullWidget)的方式。本文是《无限滚动与动态加载的实现》(地址:https://jclee95.blog.csdn.net/article/details/133340592)的另外一个版本,抛弃了Flutter有状态组件,取而代之的是GetX简单状态管理。以GetX简单状态管理的方式实现的。基本过程和思路一样,仅仅是状态管理方式上不一样。另外对于部分效果进行了简单的改进。



1. 无限滚动列表

在 Flutter 中,实现一个无尽滚动列表通常涉及使用 ListView、ListView.builder 或 ListView.separated 组件,并结合数据源和滚动控制器。这使得您可以加载和显示大量数据,只有在需要时才会动态加载更多数据,以实现无尽滚动效果。

2. 模拟滚动列表的基本实现举例(ListView.builder)

2.1 实现思路与步骤介绍

以下是实现 Flutter 无尽滚动列表的一般步骤:

准备数据源

首先需要有一个数据源。比如一个列表或一个数据库查询结果,或者是网络请求的数据,以供列表渲染。通常,这些数据应该是 按需加载 的,而不是一次性加载所有数据。

创建滚动控制器

通过 ScrollController 创建一个滚动控制器,以便监听列表的滚动事件。这将帮助您确定何时加载更多数据。

构建列表视图

使用 ListView.builder 构建一个列表视图,该构造函数会创建一个只渲染可见项的列表。通过指定 itemBuilder 参数来定义如何渲染每个列表项。

设置滚动监听

将滚动控制器添加到列表视图,并使用 addListener 监听滚动事件。当用户滚动列表时,可以在适当的时候触发加载更多数据的操作。

加载更多数据

在需要加载更多数据时,您可以调用数据源的方法或请求数据。这可以是从网络获取数据、从本地数据库查询数据或其他方式。一旦数据准备好,将其添加到数据源中,然后通知列表视图重新构建。

更新列表视图

当有新数据可用时,调用 setState 方法以通知 Flutter 重新构建列表视图。这将导致列表视图加载和显示新数据。

2.2 一个简单例子

依据 2.1 小节的步骤,实现一个模拟无线滚动的例子如下:

import 'package:flutter/material.dart';
import 'package:get/get.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({Key? key}) : super(key: key);Widget build(BuildContext context) {return const MaterialApp(home: InfiniteScrollList(),);}
}class Controller extends GetxController {ScrollController scrollController = ScrollController();List<String> items = <String>[];var isLoading = false;void loadMore() {if (scrollController.position.pixels ==scrollController.position.maxScrollExtent &&!isLoading) {isLoading = true;update();// 模拟加载1秒延时Future.delayed(const Duration(seconds: 1), () {// 生成3项假数据插入items.addAll(List.generate(3, (index) => 'Item ${index + items.length}'));isLoading = false;update();});}}static Controller get to => Get.find();void onInit() {// 初始化一些数据items = List.generate(20, (index) => 'Item $index');scrollController = ScrollController();isLoading = false;// 添加滚动监听器scrollController.addListener(loadMore);super.onInit();}void onClose() {scrollController.dispose();super.onClose();}
}class InfiniteScrollList extends StatelessWidget {const InfiniteScrollList({super.key});Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('无尽滚动列表'),),body: GetBuilder<Controller>(init: Controller(),builder: (controller) {return Column(children: [Expanded(child: ListView.builder(controller: controller.scrollController,itemCount:controller.items.length + (controller.isLoading ? 1 : 0),itemBuilder: (context, index) {if (index < controller.items.length) {return Card(elevation: 3,margin: const EdgeInsets.all(8),child: ListTile(title: Text(controller.items[index]),// 在这里添加商品卡片的内容// 例如:商品图片、描述、价格等),);} else {return const Padding(padding: EdgeInsets.all(12.0),child: Center(child: SizedBox(width: 18.0,height: 18.0,child: CircularProgressIndicator(valueColor: AlwaysStoppedAnimation<Color>(Colors.grey,), // 颜色为灰色strokeWidth: 3, // 线宽为3),),),);}},),),],);},),);}
}

上面的代码中,InfiniteScrollList 是一个 StatefulWidget,它包含了一个可无限滚动的列表视图,可以自动加载更多数据。首先,初始状态下,列表包含20个整数项。当用户滚动到列表的底部时,它会模拟加载更多数据,每次加载三个(生成的假数据)。当加载更多数据时,会显示一个加载指示器。效果如图所示:

在这里插入图片描述

通过这些步骤,可以实现一个无限滚动列表,用户可以滚动并加载更多数据,从而创建无限滚动的体验。这对于需要显示大量数据的应用程序非常有用,例如社交媒体新闻源或产品列表。

这个代码实现了一个无限滚动的列表,其中使用了GetX来进行简单的状态管理。以下是对这个代码实现无限滚动的解释:

  1. 创建一个Controller类,该类继承自GetxController,用于管理状态和滚动。
class Controller extends GetxController {ScrollController scrollController = ScrollController();List<String> items = <String>[];var isLoading = false;// 省略了其它方法
}
  • scrollController 用于管理列表的滚动。
  • items 用于存储列表中的数据项。
  • isLoading 用于标识是否正在加载更多数据。
  1. Controller类中定义了一个名为loadMore的方法,该方法用于检测是否需要加载更多数据。
void loadMore() {if (scrollController.position.pixels ==scrollController.position.maxScrollExtent &&!isLoading) {isLoading = true;update();// 模拟加载1秒延时Future.delayed(const Duration(seconds: 1), () {// 生成3项假数据插入items.addAll(List.generate(3, (index) => 'Item ${index + items.length}'));isLoading = false;update();});}
}
  • loadMore 方法会在滚动到列表底部且不处于加载状态时触发。
  • 在加载数据时,它模拟了1秒的延时,然后生成3个假数据项,将它们添加到 items 列表中。
  • 加载完成后,将 isLoading 设置为 false 并调用 update 方法通知界面更新。
  1. Controller类的onInit方法中初始化了一些数据,并为scrollController添加了滚动监听器。

void onInit() {// 初始化一些数据items = List.generate(20, (index) => 'Item $index');scrollController = ScrollController();isLoading = false;// 添加滚动监听器scrollController.addListener(loadMore);super.onInit();
}
  • 在初始化时,生成了20个假数据项并将它们存储在 items 列表中。
  • 创建了 scrollController 并将滚动监听器 loadMore 添加到它上面。
  1. InfiniteScrollList小部件中使用了 GetBuilder,它监听 Controller 的状态变化并更新UI。
body: GetBuilder<Controller>(init: Controller(),builder: (controller) {return Column(children: [Expanded(child: ListView.builder(controller: controller.scrollController,itemCount: controller.items.length + (controller.isLoading ? 1 : 0),itemBuilder: (context, index) {if (index < controller.items.length) {// 渲染数据项} else {// 渲染加载指示器}},),),],);},
),
  • GetBuilder 会监听 Controller 的状态变化,包括 itemsisLoading,以便在数据加载时更新UI。
  • ListView.builder 用于构建列表,它的 itemCount 根据数据项的数量和加载状态动态确定。
  • itemBuilder 中,根据索引渲染数据项或加载指示器。

总结:这个代码通过GetX库实现了一个无限滚动的列表,可以动态加载数据。滚动到列表底部时,它会触发加载更多数据的操作,加载完成后更新UI以显示新的数据项。GetX的简单状态管理使得管理状态变得更加容易。

3. 改造1:仿淘宝无线滚动网格基本实现举例(GridView.builder)

基本原理与无线滚动的列表类似,要改造为模拟无限滚动的 GridView需要进行的步骤包括:

  1. 创建数据源:首先,您需要准备一个数据源,这可以是一个包含商品信息的列表。
  2. 创建滚动视图:替换 ListView.builder 为 GridView.builder,以创建网格视图。设置 gridDelegate 来指定列数和布局。
  3. 滚动监听:使用 ScrollController 监听滚动事件,类似于之前的示例,以确定何时触发加载更多数据的操作。
  4. 动态加载触发:在滚动监听器中,检查滚动位置是否接近底部,如果是,触发加载更多数据的操作。
  5. 更新数据源:当触发加载更多数据时,更新数据源,通常是从网络或其他数据源获取新数据,并将其添加到数据源中。
  6. 重新构建UI:使用 setState() 来通知 Flutter 重新构建 UI,以显示新加载的数据。

具体的实现代码如下:

import 'package:flutter/material.dart';
import 'package:get/get.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({Key? key}) : super(key: key);Widget build(BuildContext context) {return const MaterialApp(home: InfiniteScrollGrid(),);}
}class Controller extends GetxController {ScrollController scrollController = ScrollController();List<String> items = <String>[];var isLoading = false;void loadMore() {if (scrollController.position.pixels ==scrollController.position.maxScrollExtent &&!isLoading) {isLoading = true;update();// 模拟加载1秒延时Future.delayed(const Duration(seconds: 1), () {// 生成3项假数据插入items.addAll(List.generate(3, (index) => 'Item ${index + items.length}'));isLoading = false;update();});}}static Controller get to => Get.find();void onInit() {// 初始化一些数据items = List.generate(20, (index) => 'Item $index');scrollController = ScrollController();isLoading = false;// 添加滚动监听器scrollController.addListener(loadMore);super.onInit();}void onClose() {scrollController.dispose();super.onClose();}
}class InfiniteScrollGrid extends StatelessWidget {const InfiniteScrollGrid({super.key});Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('无尽滚动网格'),),body: GetBuilder<Controller>(init: Controller(),builder: (controller) {return Column(children: [Expanded(child: GridView.builder(controller: controller.scrollController,gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, // 列数childAspectRatio: 0.7, // 网格项的宽高比),itemCount: controller.items.length,itemBuilder: (context, index) {return Card(elevation: 3,margin: const EdgeInsets.all(8),child: Text(controller.items[index]),);},),),if (controller.isLoading)const Padding(padding: EdgeInsets.all(12.0),child: Center(child: SizedBox(width: 18.0,height: 18.0,child: CircularProgressIndicator(valueColor: AlwaysStoppedAnimation<Color>(Colors.grey,), // 颜色为灰色strokeWidth: 3, // 线宽为3),),),),],);},),);}
}

这段代码的实现效果为:

在这里插入图片描述

import 'package:flutter/material.dart';
import 'package:get/get.dart';void main() {runApp(const MyApp());
}class MyApp extends StatelessWidget {const MyApp({Key? key}) : super(key: key);Widget build(BuildContext context) {return const MaterialApp(home: InfiniteScrollGrid(),);}
}class Controller extends GetxController {ScrollController scrollController = ScrollController();List<String> items = <String>[];var isLoading = false;void loadMore() {if (scrollController.position.pixels ==scrollController.position.maxScrollExtent &&!isLoading) {isLoading = true;update();// 模拟加载1秒延时Future.delayed(const Duration(seconds: 1), () {// 生成3项假数据插入items.addAll(List.generate(3, (index) => 'Item ${index + items.length}'));isLoading = false;update();});}}static Controller get to => Get.find();void onInit() {// 初始化一些数据items = List.generate(20, (index) => 'Item $index');scrollController = ScrollController();isLoading = false;// 添加滚动监听器scrollController.addListener(loadMore);super.onInit();}void onClose() {scrollController.dispose();super.onClose();}
}class InfiniteScrollGrid extends StatelessWidget {const InfiniteScrollGrid({super.key});Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: const Text('无尽滚动网格'),),body: GetBuilder<Controller>(init: Controller(),builder: (controller) {return Column(children: [Expanded(child: GridView.builder(controller: controller.scrollController,gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2, // 列数childAspectRatio: 0.7, // 网格项的宽高比),itemCount: controller.items.length,itemBuilder: (context, index) {return Card(elevation: 3,margin: const EdgeInsets.all(8),child: Column(crossAxisAlignment: CrossAxisAlignment.start,children: [// 商品图片Image.network('https://csdn-ebook-resources.oss-cn-beijing.aliyuncs.com/images/4e05b89fedf043f1964e73aa729d21fb/cover.jpg',width: double.infinity, // 图片宽度占满卡片宽度height: 200, // 图片高度fit: BoxFit.cover, // 图片填充方式),// 商品名称const Padding(padding: EdgeInsets.all(8.0),child: Text('商品名称',style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),),),// 商品描述const Padding(padding: EdgeInsets.all(8.0),child: Text('商品描述',style: TextStyle(fontSize: 16),),),// 商品价格const Padding(padding: EdgeInsets.all(8.0),child: Text('¥ 99.99',style: TextStyle(fontSize: 18, color: Colors.red),),),// 在这里添加其他商品信息],),);},),),if (controller.isLoading)const Padding(padding: EdgeInsets.all(12.0),child: Center(child: SizedBox(width: 18.0,height: 18.0,child: CircularProgressIndicator(valueColor: AlwaysStoppedAnimation<Color>(Colors.grey,), // 颜色为灰色strokeWidth: 3, // 线宽为3),),),),],);},),);}
}

在这里插入图片描述

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

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

相关文章

JavaScript系列从入门到精通系列第十二篇:JavaScript中对象的简介和对象的基本操作以及JavaScript中的属性值和属性名

文章目录 前言 一&#xff1a;对象分类 1&#xff1a;内建对象 2&#xff1a;宿主对象 3&#xff1a;自建对象 二&#xff1a;对象的基本操作 1&#xff1a;创建对象 2&#xff1a;向对象中添加属性 3&#xff1a;读取对象中的属性 4&#xff1a;修改对象中的属性 三…

问题: 视频颜色问题,偏绿

参考 什么是杜比视界&#xff1f; - https://www.youtube.com/watch?vldXDQ6VlC7g 【哈士亓说】07&#xff1a;HDR、杜比视界究竟是个啥&#xff1f;为什么这个视频还不是HDR视频&#xff1f; - https://www.youtube.com/watch?vrgb9Xg3cJns 正文 视频应该是 杜比视界 电…

231003-四步MacOS-iPadOS设置无线竖屏随航SideCar

Step 0&#xff1a;MacOS到iPad无线竖屏随航显示&#xff0c;最终效果 Step 1&#xff1a; 下载 Better Display Step 2&#xff1a;在设置中新建虚拟屏幕&#xff0c;创建虚拟屏幕 Step 3&#xff1a;进行如下设置 Step 4&#xff1a;注意事项 ⚠️ 设置后的虚拟屏幕与Sideca…

excel中将一个sheet表根据条件分成多个sheet表

有如下excel表&#xff0c;要求&#xff1a;按月份将每月的情况放在一个sheet中。 目测有6个月&#xff0c;就应该有6个sheet&#xff0c;每个sheet中体现本月的情况。 一、首先增加一个辅助列&#xff0c;月份&#xff0c;使用month函数即可。 填充此列所有。然后复制【月份】…

知识分享 钡铼网关功能介绍:使用SSLTLS 加密,保证MQTT通信安全

背景 为了使不同的设备或系统能够相互通信&#xff0c;让旧有系统和新的系统可以集成&#xff0c;通信更加灵活和可靠。以及将数据从不同的来源收集并传输到不同的目的地&#xff0c;实现数据的集中管理和分发。 通信网关完美克服了这一难题&#xff0c;485或者网口的设备能通过…

Docker项目部署

目录 一、前端项目部署 1、上传文件 2、开启容器 3、测试 二、后端项目部署 1、打包java项目 2、将jar包和Dockerfile文件长传到Linux系统 3、构建镜像 4、开启容器 5、测试 一、前端项目部署 1、上传文件 里面包括页面和配置文件 worker_processes 1;events {worker…

【Pytorch笔记】4.梯度计算

深度之眼官方账号 - 01-04-mp4-计算图与动态图机制 前置知识&#xff1a;计算图 可以参考我的笔记&#xff1a; 【学习笔记】计算机视觉与深度学习(2.全连接神经网络) 计算图 以这棵计算图为例。这个计算图中&#xff0c;叶子节点为x和w。 import torchw torch.tensor([1.]…

分类预测 | MATLAB实现SSA-FS-SVM麻雀算法同步优化特征选择结合支持向量机分类预测

分类预测 | MATLAB实现SSA-FS-SVM麻雀算法同步优化特征选择结合支持向量机分类预测 目录 分类预测 | MATLAB实现SSA-FS-SVM麻雀算法同步优化特征选择结合支持向量机分类预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 MATLAB实现SSA-FS-SVM麻雀算法同步优化特征选择结…

快速选择排序

"你经过我每个灿烂时刻&#xff0c;我才真正学会如你般自由" 前些天有些无聊&#xff0c;想试试自己写的快排能否过leetcode上的排序算法题。结果是&#xff0c;不用截图可想而知&#xff0c;肯定是没过的&#xff0c;否则也不会有这篇文章的产出。 这份快排算法代码…

HCQ1-1300-D【高速输入】

因为我的PLC固件比较旧。所以有些限制。【比如&#xff1a;编译不报错&#xff0c;下载PLC程序就报故障】我的PLC的高速输入类型只能是【hsi_ref】 所以&#xff0c;程序添加的高速输入模块只能是【1.0.1.0】版本 如果固件版本低&#xff0c;看下固件能支持的类型。选错的话&am…

苹果曾考虑基于定位控制AirPods Pro自适应音频

在一次最近的采访中&#xff0c;苹果公司的高管Ron Huang和Eric Treski透露&#xff0c;他们在开发AirPods Pro自适应音频功能时&#xff0c;曾考虑使用GPS信号来控制音频级别。这个有趣的细节打破了我们对AirPods Pro的固有认知&#xff0c;让我们对苹果的创新思维有了更深的…

Python学习笔记之运算符的使用

Python学习笔记之运算符的使用 整型&#xff1a;二进制0b100十进制4、八进制0o100十进制64、十进制100、十六进制0x100十进制256浮点型&#xff1a;123.456&#xff0c;1.23456e2字符串型&#xff1a;‘Hello’&#xff0c;“Hello”布尔型&#xff1a;True、False复数型&…

电子计算机核心发展(继电器-真空管-晶体管)

目录 继电器 最大的机电计算机之一——哈弗Mark1号&#xff0c;IBM1944年 背景 组成 性能 核心——继电器 简介 缺点 速度 齿轮磨损 Bug的由来 真空管诞生 组成 控制开关电流 继电器对比 磨损 速度 缺点 影响 代表 第一个可编程计算机 第一个真正通用&am…

ssm+vue的图书馆书库管理系统(有报告)。Javaee项目,ssm vue前后端分离项目。

演示视频&#xff1a; ssmvue的图书馆书库管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;ssm vue前后端分离项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构…

OpenCV 基础图像处理

1、生成图像 cv2.imread是OpenCV库中的一个函数&#xff0c;用于读取图像文件。它接受一个参数&#xff0c;即要读取的图像文件的路径&#xff0c;返回一个多维数组&#xff0c; 表示图像的像素值。该函数的常用参数包括&#xff1a;flags&#xff1a;指定读取图像的方式&#…

python——Django框架

一、基本介绍 Django 是一个由 Python 编写的一个开放源代码的 Web 应用框架。 使用 Django&#xff0c;只要很少的代码&#xff0c;Python 的程序开发人员就可以轻松地完成一个正式网站所需要的大部分内容&#xff0c;并进一步开发出全功能的 Web 服务 Django 本身基于 MVC …

【已解决】opencv 交叉编译 ffmpeg选项始终为NO

一、opencv 交叉编译没有 ffmpeg &#xff0c;会导致视频打不开 在交叉编译时候&#xff0c;发现在 pc 端能用 opencv 打开的视频&#xff0c;但是在 rv1126 上打不开。在网上查了很久&#xff0c;原因可能是 交叉编译过程 ffmpeg 造成的。之前 ffmpeg 是直接用 apt 安装的&am…

asp.net core 远程调试

大概说下过程&#xff1a; 1、站点发布使用Debug模式 2、拷贝到远程服务器&#xff0c;以及iis创建站点。 3、本地的VS2022的安装目录&#xff1a;C:\Program Files\Microsoft Visual Studio\2022\Professional\Common7\IDE下找Remote Debugger 你的服务器是64位就拷贝x64的目…

【从入门到起飞】IO高级流(1)(缓冲流,转换流,序列化流,反序列化流)

&#x1f38a;专栏【JavaSE】 &#x1f354;喜欢的诗句&#xff1a;天行健&#xff0c;君子以自强不息。 &#x1f386;音乐分享【如愿】 &#x1f384;欢迎并且感谢大家指出小吉的问题&#x1f970; 文章目录 &#x1f384;缓冲流&#x1f354;字节缓冲流&#x1f6f8;一次读取…

【通意千问】大模型GitHub开源工程学习笔记(1)--依赖库

9月25日&#xff0c;阿里云开源通义千问140亿参数模型Qwen-14B及其对话模型Qwen-14B-Chat,免费可商用。 立马就到了GitHub去fork。 GitHub&#xff1a; GitHub - QwenLM/Qwen: The official repo of Qwen (通义千问) chat & pretrained large language model proposed b…