Flutter下拉刷新上拉加载侧拉刷新插件:easy_refresh全面使用指南

easy_refresh 是 Flutter 生态中一款功能强大、高度可定制的下拉刷新与上拉加载更多插件,相比 Flutter 原生 RefreshIndicator,它支持更多刷新样式、自定义动画、多状态切换等高级特性,已成为 Flutter 项目中处理刷新加载场景的首选方案之一。

1. 快速集成

在项目 pubspec.yaml 文件中添加最新版本依赖,可前往 pub.dev 查看最新版本:

yaml 复制代码
dependencies:
  flutter:
    sdk: flutter
  easy_refresh: ^3.9.0 # 以实际最新版本为准

在需要使用的 Dart 文件中导入插件:

dart 复制代码
import 'package:easy_refresh/easy_refresh.dart';

2. 核心 API 介绍

以下表格汇总了 easy_refresh 的核心 API、功能说明及使用方式,覆盖核心组件与关键配置:

API 名称 类型 功能说明 使用方式
EasyRefresh 组件(Widget) 核心容器组件,包裹需要实现刷新/加载的内容,提供刷新加载能力 作为父容器包裹 ListView/GridView 等滚动组件,配置 onRefresh/onLoad 回调
onRefresh 回调函数(Future Function()?) 下拉刷新触发的回调,用于执行刷新数据逻辑(如重新请求接口) onRefresh: () async { await loadRefreshData(); }
onLoad 回调函数(Future Function()?) 上拉加载更多触发的回调,用于执行加载下一页数据逻辑 onLoad: () async { await loadMoreData(); }
header 组件(Widget?) 下拉刷新头部样式(指示器),支持内置样式与自定义 内置样式:header: ClassicHeader() 自定义:header: CustomHeader()
footer 组件(Widget?) 上拉加载底部样式(指示器),支持内置样式与自定义 内置样式:footer: ClassicFooter() 自定义:footer: CustomFooter()
EasyRefreshController 控制器类 手动控制刷新/加载状态(如主动触发刷新、结束加载状态) 1. 初始化:final controller = EasyRefreshController() 2. 主动刷新:controller.callRefresh() 3. 释放资源:@override void dispose() { controller.dispose(); super.dispose(); }
finishRefresh 控制器方法 结束下拉刷新状态,可指定刷新结果(成功/失败/无更多) controller.finishRefresh(RefreshResult.success);(无更多:RefreshResult.noMore
finishLoad 控制器方法 结束上拉加载状态,可指定加载结果(成功/失败/无更多) controller.finishLoad(LoadResult.success);(无更多:LoadResult.noMore
enableRefresh 布尔值 是否启用下拉刷新功能,默认 true enableRefresh: false(禁用下拉刷新)
enableLoad 布尔值 是否启用上拉加载功能,默认 true enableLoad: false(禁用上拉加载)

3. 常用内置样式

easy_refresh 提供了多种开箱即用的头部/底部样式,满足大部分常规场景需求,核心样式如下:

样式名称 类型 适用场景 使用示例
ClassicHeader 下拉头部 常规列表刷新(仿原生样式) header: ClassicHeader(textColor: Colors.black)
ClassicFooter 上拉底部 常规列表加载更多(仿原生样式) footer: ClassicFooter(loadText: "正在加载...")
BallPulseHeader 下拉头部 简约加载动画(小球脉冲效果) header: BallPulseHeader(color: Colors.blue)
BallPulseFooter 上拉底部 简约加载动画(小球脉冲效果) footer: BallPulseFooter(color: Colors.blue)
MaterialHeader 下拉头部 Material Design 风格(与原生 RefreshIndicator 一致) header: MaterialHeader()
MaterialFooter 上拉底部 Material Design 风格 footer: MaterialFooter()

4. 完整使用案例

以下案例实现了一个带下拉刷新、上拉加载更多的列表页面,包含数据模拟、状态控制、样式配置等核心功能,代码简洁可直接运行。

4.1. 完整代码

dart 复制代码
import 'package:flutter/material.dart';
import 'package:easy_refresh/easy_refresh.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'easy_refresh 使用案例',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: const EasyRefreshDemo(),
    );
  }
}

class EasyRefreshDemo extends StatefulWidget {
  const EasyRefreshDemo({super.key});

  @override
  State<EasyRefreshDemo> createState() => _EasyRefreshDemoState();
}

class _EasyRefreshDemoState extends State<EasyRefreshDemo> {
  // 1. 初始化 EasyRefresh 控制器
  final EasyRefreshController _controller = EasyRefreshController();
  // 列表数据
  List<String> _listData = [];
  // 当前页码
  int _currentPage = 1;
  // 每页数据量
  static const int _pageSize = 10;

  @override
  void initState() {
    super.initState();
    // 初始化加载第一页数据
    _loadRefreshData();
  }

  // 2. 下拉刷新数据逻辑(重置页码,重新加载第一页)
  Future<void> _loadRefreshData() async {
    try {
      // 模拟网络请求延迟
      await Future.delayed(const Duration(seconds: 1));
      // 重置页码
      _currentPage = 1;
      // 模拟数据
      List<String> newData = List.generate(_pageSize, (index) => "刷新数据 ${index + 1}");
      setState(() {
        _listData = newData;
      });
      // 结束刷新状态(成功)
      _controller.finishRefresh(RefreshResult.success);
    } catch (e) {
      // 结束刷新状态(失败)
      _controller.finishRefresh(RefreshResult.fail);
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text("刷新失败,请重试!")),
        );
      }
    }
  }

  // 3. 上拉加载更多数据逻辑(页码+1,加载下一页)
  Future<void> _loadMoreData() async {
    try {
      // 模拟网络请求延迟
      await Future.delayed(const Duration(seconds: 1));
      // 页码+1
      _currentPage++;
      // 模拟数据
      List<String> moreData = List.generate(_pageSize, (index) => "加载数据 ${(_currentPage - 1) * _pageSize + index + 1}");
      setState(() {
        _listData.addAll(moreData);
      });

      // 模拟无更多数据(第3页后无更多)
      if (_currentPage >= 3) {
        _controller.finishLoad(LoadResult.noMore);
      } else {
        _controller.finishLoad(LoadResult.success);
      }
    } catch (e) {
      // 结束加载状态(失败)
      _controller.finishLoad(LoadResult.fail);
      // 页码回退
      _currentPage--;
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text("加载失败,请重试!")),
        );
      }
    }
  }

  @override
  void dispose() {
    // 释放控制器资源
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("easy_refresh 示例")),
      body: EasyRefresh(
        // 控制器
        controller: _controller,
        // 下拉头部样式
        header: ClassicHeader(
          refreshText: "下拉可刷新",
          refreshingText: "正在刷新...",
          refreshedText: "刷新完成",
          textColor: Colors.black87,
        ),
        // 上拉底部样式
        footer: ClassicFooter(
          loadText: "上拉可加载",
          loadingText: "正在加载...",
          loadedText: "加载完成",
          noMoreText: "已加载全部数据",
          textColor: Colors.black87,
        ),
        // 下拉刷新回调
        onRefresh: _loadRefreshData,
        // 上拉加载回调
        onLoad: _loadMoreData,
        // 启用刷新/加载
        enableRefresh: true,
        enableLoad: true,
        // 列表内容
        child: ListView.builder(
          itemCount: _listData.length,
          itemBuilder: (context, index) {
            return ListTile(
              title: Text(_listData[index]),
              leading: CircleAvatar(child: Text("${index + 1}")),
            );
          },
        ),
      ),
    );
  }
}

4.2. 案例说明

  1. 控制器使用 :通过 EasyRefreshController 手动控制刷新/加载状态,避免异步请求后状态未及时更新的问题;
  2. 数据模拟 :使用 Future.delayed 模拟网络请求延迟,List.generate 生成测试数据,可直接替换为真实接口请求;
  3. 状态处理:区分刷新/加载的成功、失败、无更多三种状态,提升用户体验;
  4. 样式自定义 :通过 ClassicHeader/ClassicFooter 自定义提示文字与文字颜色,适配不同主题风格;
  5. 资源释放 :在 dispose 方法中释放控制器资源,避免内存泄漏。

5. 核心特性总结

  1. 高度可定制:支持自定义头部/底部样式、刷新动画、触发阈值等,满足个性化需求;
  2. 功能全面:支持下拉刷新、上拉加载、手动触发刷新/加载、无更多数据状态提示等;
  3. 性能优异:滚动监听优化,无冗余渲染,适配 ListView/GridView/ScrollView 等所有滚动组件;
  4. 兼容性好:支持 Flutter 多平台(Android、iOS、Web、桌面端),兼容最新 Flutter 版本。

6. 扩展使用

  • 自定义头部/底部 :继承 Header/Footer 类,实现自定义布局与动画,满足特殊UI需求;
  • 嵌套滚动支持 :适配 NestedScrollView,可实现折叠导航栏+下拉刷新的组合场景;
  • 全局配置 :通过 EasyRefresh.defaultHeader/EasyRefresh.defaultFooter 设置全局默认样式,减少重复代码。

7. 总结

easy_refresh 是Flutter开发中轻量化、高适配、易拓展的下拉刷新与上拉加载插件,相比原生刷新组件,它解决了样式单一、状态控制繁琐、多端适配差的痛点,核心优势与使用要点总结如下:

  1. 接入成本极低,仅需三步即可实现基础刷新加载功能,代码简洁无冗余,新手也能快速上手;
  2. 内置多款开箱即用的刷新/加载样式,同时支持高度自定义头部、底部布局与动画,适配各类UI设计需求;
  3. 提供完善的控制器API,可灵活实现手动触发刷新、多状态(成功/失败/无更多)管控,满足复杂业务场景;
  4. 全平台兼容,适配Android、iOS、Web及桌面端,且性能优异,无冗余渲染,不影响列表滚动流畅度;
  5. 支持嵌套滚动、全局样式配置等高级能力,可在项目中全局统一刷新风格,大幅减少重复开发工作。

该插件能完美覆盖Flutter项目中列表刷新、分页加载、数据重载等核心场景,是处理滚动刷新加载需求的最优选择之一。

7.1. 引用来源

  1. easy_refresh 官方仓库GitHub - flutter_easyrefresh
  2. Flutter 官方包管理平台文档pub.dev - easy_refresh
  3. 官方接口参考文档easy_refresh API 文档
  4. 官方在线演示地址easy_refresh 示例演示

本次分享就到这儿啦,我是鹏多多,深耕前端的技术创作者,如果您看了觉得有帮助,欢迎评论,关注,点赞,转发,我们下次见~

PS:在本页按F12,在console中输入document.getElementsByClassName('panel-btn')0.click();有惊喜哦~

往期文章

相关推荐
To_OC4 小时前
别再串行写 await 了,Promise.all 才是并行请求的正确打开方式
前端·javascript·promise
vipbic4 小时前
中后台越做越乱后,我用插件化把它救回来了
前端·vue.js
Hyyy4 小时前
Computer Use 适合做什么,不适合做什么——一次真实使用后的思考
前端
小和尚同志5 小时前
前端 AI 单元测试思考与落地
前端·人工智能·aigc
invicinble6 小时前
c端系统,其实更像一个信息展示平台
前端
李姆斯7 小时前
管理是否可以被完全量化
前端·产品经理·团队管理
名字还没想好☜7 小时前
Next.js 中间件实战:鉴权、重定向与 A/B 分流
开发语言·前端·javascript·中间件·react·next.js
广州灵眸科技有限公司8 小时前
瑞芯微RV1126B开发板(EASY-EAI-PI2) INI文件操作
java·前端·javascript·网络·人工智能
心中有国也有家8 小时前
AtomGit Flutter 鸿蒙客户端:ModalBottomSheet 实战
android·javascript·学习·flutter·华为·harmonyos
kaiking_g8 小时前
vue项目中,静态导入 vs 动态导入 详解
前端·javascript·vue.js