字节笔记本

2026年2月23日

Flutter 分页列表组件:PagingListWidget 实现解析

本文介绍一个 Flutter 分页列表组件 paging_list.dart 的实现,该组件封装了上拉加载、下拉刷新、多状态显示(加载中、空数据、错误、内容)等功能,基于 flutter_easyrefreshGetX 状态管理库构建。

组件概述

PagingListWidget 是一个通用的分页列表组件,继承该组件即可获得完整的分页列表功能,包括:

  • 下拉刷新:支持下拉刷新数据
  • 上拉加载:支持上拉加载更多数据
  • 多状态显示:自动处理加载中、空数据、错误、内容四种状态
  • GetX 集成:与 GetX 状态管理深度集成

核心类解析

1. PagingListWidget

泛型分页列表组件,接收两个类型参数:

  • LIST_ITEM:列表项数据类型
  • C:继承自 PagingListControl<LIST_ITEM> 的控制器类型
dart
class PagingListWidget<LIST_ITEM, C extends PagingListControl<LIST_ITEM>> extends StatelessWidget {
  final ItemBuilder<LIST_ITEM> _createItem;
  final bool _refreshEnable;    // 是否启用下拉刷新
  final bool _loadMoreEnable;   // 是否启用上拉加载

  PagingListWidget({
    bool refreshEnable: true,
    bool loadMoreEnable: true,
    @required ItemBuilder<LIST_ITEM> createItem,
  })  : this._createItem = createItem,
        this._refreshEnable = refreshEnable,
        this._loadMoreEnable = loadMoreEnable;
}

2. ListState 枚举

定义列表的四种状态:

dart
enum ListState {
  LOADING,  // 第一次显示时的 loading 状态
  CONTENT,  // 显示内容
  EMPTY,    // 显示空数据
  ERROR,    // 显示错误信息
}

3. MultiStateList

多状态列表组件,封装了 EasyRefresh 的功能,提供统一的加载、空数据、错误状态显示:

dart
class MultiStateList extends StatelessWidget {
  static const TEXT_TIP = Color(0xFF666666);

  final Widget _init;      // 初始化加载视图
  final Widget _empty;     // 空数据视图
  final Widget _error;     // 错误视图
  final RetryLoad _retry;  // 重试回调
  final OnRefresh _onRefresh;
  final LoadMore _loadMore;
  final ListState _listState;
  final Widget _child;     // 列表内容

  // EasyRefresh 相关 Key
  final GlobalKey<EasyRefreshState> _easyRefreshKey;
  final GlobalKey<RefreshHeaderState> _headerKey;
  final GlobalKey<RefreshFooterState> _footerKey;
}

默认视图实现

加载中视图

dart
Widget getDefaultInitView() {
  return Center(
    child: Container(
      width: 50,
      height: 50,
      child: CircularProgressIndicator(),
    ),
  );
}

空数据视图

dart
Widget getDefaultEmpty(BuildContext context) {
  return Center(
    child: Material(
      color: Colors.transparent,
      child: InkWell(
        onTap: () => _retry(context),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            Image(
              image: AssetImage("assets/images/empty.png", package: "base_lib"),
              width: 80,
              height: 80,
            ),
            Text("暂无数据"),
            Text("点击重试", style: TextStyle(color: TEXT_TIP)),
          ],
        ),
      ),
    ),
  );
}

错误视图

dart
Widget getDefaultError(BuildContext context) {
  return Center(
    child: Material(
      color: Colors.transparent,
      child: InkWell(
        onTap: () => _retry(context),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            Image(
              image: AssetImage("assets/images/error.png", package: "base_lib"),
              width: 100,
              height: 80,
            ),
            Text("加载失败"),
            Text("点击重试", style: TextStyle(color: TEXT_TIP)),
          ],
        ),
      ),
    ),
  );
}

使用示例

基础用法

dart
PagingListWidget<ArticleItem, ArticleController>(
  createItem: (context, index, data) {
    return ArticleCard(item: data);
  },
)

禁用刷新或加载

dart
PagingListWidget<ArticleItem, ArticleController>(
  refreshEnable: false,   // 禁用下拉刷新
  loadMoreEnable: true,   // 启用上拉加载
  createItem: (context, index, data) => ArticleCard(item: data),
)

依赖说明

该组件依赖以下包:

yaml
dependencies:
  flutter_easyrefresh: ^2.x  # 下拉刷新上拉加载
  get: ^4.x                   # 状态管理

控制器要求

使用该组件需要配合 PagingListControl 控制器,控制器需要提供以下属性:

dart
abstract class PagingListControl<T> extends GetxController {
  GlobalKey<EasyRefreshState> get easyRefreshKey;
  GlobalKey<RefreshHeaderState> get headerKey;
  GlobalKey<RefreshFooterState> get footerKey;
  ListState get listState;
  List<T> get dataList;

  Future<void> onRefresh();   // 刷新方法
  Future<void> loadMore();    // 加载更多方法
  void onRetry(BuildContext context);  // 重试方法
}

源码链接

分享: